#!/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$' allowed_multi_use = list(map(lambda x: ipaddress.ip_network(x, strict=True), [ '192.168.0.0/22', '192.168.0.0/16', '192.168.0.0/24', '192.168.1.0/24', '192.168.178.0/24', ])) def check_double_ip(): pool = defaultdict(list) try: for host in gformat.get_hostlist(): print("## Processing host %-25s: " % host, end='') datadump = gformat.get_yaml(host,add_version_info=False) masterip_addr = ipaddress.IPv4Interface(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(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) as 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())