#!/usr/bin/env python # vim:ts=2:et:sw=2:ai # # Build topological network graph # Rick van der Zwet import gformat import sys import ipaddress from collections import defaultdict __version__ = '$Id: syntax-checker.py 14025 2018-01-22 12:49:48Z rick $' allowed_multi_use = map(lambda x: ipaddress.ip_network(x, strict=True), [ u'192.168.0.0/22', u'192.168.0.0/16', u'192.168.0.0/24', u'192.168.1.0/24', u'192.168.178.0/24', ]) def check_double_ip(): pool = defaultdict(list) try: for host in gformat.get_hostlist(): print "## Processing host %-25s: " % host, datadump = gformat.get_yaml(host,add_version_info=False) masterip_addr = ipaddress.IPv4Interface(unicode(datadump['masterip'])) masterip_is_used = False # Check syntax of defined variables _ = gformat.generate_wleiden_yaml(datadump) try: # Process interfaces iface_keys = [elem for elem in datadump.keys() if (elem.startswith('iface_') and not "lo0" in elem)] for iface_key in iface_keys: # Extra (descriptive entries) are ignored if '_extra' in iface_key: continue # Process actual and virtual IP (avoiding clashes with nanostation IP) for entry in ['ip', 'ns_ip']: if entry in datadump[iface_key]: addr = ipaddress.IPv4Interface(unicode(datadump[iface_key][entry])) if masterip_addr in addr.network: masterip_is_used = True pool[addr.network].append((host, iface_key, entry, addr)) # Add masterip to the list if IP has not been defined at interface if not masterip_is_used: pool[masterip_addr.network].append((host, 'masterip', '', masterip_addr)) print "OK" except (KeyError, ValueError), e: print "[ERROR] in '%s' interface '%s' (%s)" % (host, iface_key, e) raise except Exception as e: raise sys.exit(1) errors = 0 keys = sorted(pool.keys(),reverse=True) for i,network in enumerate(keys): if not network in allowed_multi_use: for network2 in keys[i+1:]: if not network2 in allowed_multi_use and network2.overlaps(network): errors += 1 print "[ERROR#%i] network %s overlaps with %s:" % (errors, network, network2) for (host, key, entry, addr) in sorted(pool[network] + pool[network2]): print " - %-20s - %-20s - %-5s - %s" % (host, key, entry, addr) leden = sorted(pool[network]) for i,lid in enumerate(leden): for lid2 in leden[i+1:]: if lid[3] == lid2[3]: errors += 1 print "[ERROR#%i] Multiple usages of IP %s:" % (errors, lid[3]) print " - %-20s - %-20s - %-5s" % (lid[0], lid[1], lid[2]) print " - %-20s - %-20s - %-5s" % (lid2[0], lid2[1], lid2[2]) if errors > 0: print "# %i Errors found" % errors return 1 else: print "# No multiple usages of IPs found" return 0 if __name__ == "__main__": sys.exit(check_double_ip())