source: genesis/tools/syntax-checker.py@ 14341

Last change on this file since 14341 was 14025, checked in by rick, 7 years ago

Fix overlapping IP networks

The syntax checker did not check for overlapping network ranges. For example
/24 defined at Dwars overlapped with /23 of Meerburgkerk. This is causing
issues with routing and network propogation.

While here ensure all ns_ip has proper subnet set

  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 3.0 KB
Line 
1#!/usr/bin/env python
2# vim:ts=2:et:sw=2:ai
3#
4# Build topological network graph
5# Rick van der Zwet <info@rickvanderzwet.nl>
6import gformat
7import sys
8import ipaddress
9
10from collections import defaultdict
11
12__version__ = '$Id: syntax-checker.py 14025 2018-01-22 12:49:48Z rick $'
13
14allowed_multi_use = map(lambda x: ipaddress.ip_network(x, strict=True), [
15 u'192.168.0.0/22',
16 u'192.168.0.0/16',
17 u'192.168.0.0/24',
18 u'192.168.1.0/24',
19 u'192.168.178.0/24',
20 ])
21
22
23
24
25
26def check_double_ip():
27 pool = defaultdict(list)
28 try:
29 for host in gformat.get_hostlist():
30 print "## Processing host %-25s: " % host,
31 datadump = gformat.get_yaml(host,add_version_info=False)
32 masterip_addr = ipaddress.IPv4Interface(unicode(datadump['masterip']))
33 masterip_is_used = False
34
35 # Check syntax of defined variables
36 _ = gformat.generate_wleiden_yaml(datadump)
37 try:
38 # Process interfaces
39 iface_keys = [elem for elem in datadump.keys() if (elem.startswith('iface_') and not "lo0" in elem)]
40 for iface_key in iface_keys:
41 # Extra (descriptive entries) are ignored
42 if '_extra' in iface_key:
43 continue
44
45 # Process actual and virtual IP (avoiding clashes with nanostation IP)
46 for entry in ['ip', 'ns_ip']:
47 if entry in datadump[iface_key]:
48 addr = ipaddress.IPv4Interface(unicode(datadump[iface_key][entry]))
49 if masterip_addr in addr.network:
50 masterip_is_used = True
51 pool[addr.network].append((host, iface_key, entry, addr))
52
53
54 # Add masterip to the list if IP has not been defined at interface
55 if not masterip_is_used:
56 pool[masterip_addr.network].append((host, 'masterip', '', masterip_addr))
57
58 print "OK"
59 except (KeyError, ValueError), e:
60 print "[ERROR] in '%s' interface '%s' (%s)" % (host, iface_key, e)
61 raise
62 except Exception as e:
63 raise
64 sys.exit(1)
65
66 errors = 0
67 keys = sorted(pool.keys(),reverse=True)
68
69 for i,network in enumerate(keys):
70 if not network in allowed_multi_use:
71 for network2 in keys[i+1:]:
72 if not network2 in allowed_multi_use and network2.overlaps(network):
73 errors += 1
74 print "[ERROR#%i] network %s overlaps with %s:" % (errors, network, network2)
75 for (host, key, entry, addr) in sorted(pool[network] + pool[network2]):
76 print " - %-20s - %-20s - %-5s - %s" % (host, key, entry, addr)
77
78 leden = sorted(pool[network])
79 for i,lid in enumerate(leden):
80 for lid2 in leden[i+1:]:
81 if lid[3] == lid2[3]:
82 errors += 1
83 print "[ERROR#%i] Multiple usages of IP %s:" % (errors, lid[3])
84 print " - %-20s - %-20s - %-5s" % (lid[0], lid[1], lid[2])
85 print " - %-20s - %-20s - %-5s" % (lid2[0], lid2[1], lid2[2])
86
87 if errors > 0:
88 print "# %i Errors found" % errors
89 return 1
90 else:
91 print "# No multiple usages of IPs found"
92 return 0
93
94
95if __name__ == "__main__":
96 sys.exit(check_double_ip())
97
Note: See TracBrowser for help on using the repository browser.