#!/usr/bin/env python # vim:ts=2:et:sw=2:ai # # Build topological network graph # Rick van der Zwet import cgi import gformat import re import sys import urllib import yaml import math import rdnap def get_yaml(gfile): """ Get configuration yaml for 'item'""" f = open(gfile, 'r') datadump = yaml.load(f) return datadump def write_yaml(gfile, datadump): """ Write configuration yaml for 'item'""" f = open(gfile, 'w') f.write(yaml.dump(datadump, default_flow_style=False)) f.close() def make_graph(): status = None try: stream = file('/tmp/nodemap_status.yaml','r') status = yaml.load(stream) except IOError,e: print "# Error loading status '%s'" % e f = open('kmlfile.kml', 'w') f.write(""" WirelessLeiden Nodemap 1 Generated realtime status of all Wireless Leiden AccessPoints Nodes 0 All active nodes and links """) poel = {} link_type = {} node = {} nodes = [] links = [] try: for host in gformat.get_hostlist(): fqdn = host + ".wLeiden.NET" print "## Processing host", host datadump = gformat.get_yaml(host) try: lam, phi = rdnap.rd2etrs(datadump['rdnap_x'], datadump['rdnap_y']) except ValueError: raise ValueError("Host '%s' yaml broken. Invalid rdnap_x or rdnap_y" % host) print "### RDNAP:%s,%s -> %s,%s" % (datadump['rdnap_x'], datadump['rdnap_y'], lam, phi) iface_keys = [elem for elem in datadump.keys() if (elem.startswith('iface_') and not "lo0" in elem)] for iface_key in iface_keys: l = datadump[iface_key]['ip'] addr, mask = l.split('/') addr = gformat.parseaddr(addr) mask = int(mask) addr = addr & ~((1 << (32 - mask)) - 1) if poel.has_key(addr): poel[addr] += [host] else: poel[addr] = [host] # Assume all eth2wifibridge to be 11a for a moment iface_parent = '_'.join(iface_key.split('_')[0:2]) if datadump[iface_parent].has_key('extra_type') and datadump[iface_parent]['extra_type'] == 'eth2wifibridge': link_type[addr] = '11a' else: link_type[addr] = datadump[iface_parent]['type'] print "### %s [%s] is of type %s" % (gformat.showaddr(addr), iface_key, link_type[addr]) node[host] = (lam, phi) if not status: # By default assume up node_status = "up" elif not status['node'].has_key(fqdn): node_status = "unknown" elif status['node'][fqdn] == gformat.OK: node_status = "up" elif status['node'][fqdn] == gformat.DOWN: node_status = "down" elif status['node'][fqdn] == gformat.UNKNOWN: node_status = "unknown" else: assert False, "Status cannot be generated" print "### Node status is '%s'" % node_status f.write(""" All active nodes %(nodetype)s %(nodename)s %(desc)s %(style)s %(lam)s,%(phi)s,0 """ % {'nodetype' : datadump['nodetype'], 'nodename' : datadump['nodename'], 'desc' : cgi.escape(datadump['location']), 'style' : '#node_status_' + node_status, 'lam' : lam, 'phi' : phi}) nodes += [("POINT(%s, %s)" % (lam, phi))] except (KeyError, ValueError), e: print "[FOUT] in '%s' interface '%s'" % (host,iface_key) raise sys.exit(1) f.write(""" Links 0 All links """) for addr,leden in poel.iteritems(): if not gformat.valid_addr(gformat.showaddr(addr)): print "## Adres '%s' met leden '%s' ignored'" % (gformat.showaddr(addr), ','.join(leden)) continue if link_type[addr] == '11a': weight = 2 elif link_type[addr] == 'eth': weight = 4 else: weight = 1 leden = sorted(set(leden)) for index,lid in enumerate(leden[:-1]): for buur in leden[index + 1:]: key = (lid + ".wLeiden.NET", buur + ".wLeiden.NET") rev_key = (key[1],key[0]) link_status = None if not status: # Default assume OK link_status = gformat.OK elif status['link'].has_key(key): link_status = status['link'][key] elif status['link'].has_key(rev_key): link_status = status['link'][rev_key] else: # If link is not known assume nothing link_status = gformat.UNKNOWN if link_status == gformat.OK: color = '#ffff0000' # green elif link_status == gformat.DOWN: color = '#ff0000ff' # red elif link_status == gformat.UNKNOWN: color = '#55000000' # black else: assert False, "Link status not mapped properly" f.write(""" %(name)s 0 %(desc)s 0 %(lam1)s, %(phi1)s, 0 %(lam2)s , %(phi2)s, 0 """ % { 'lam1' : node[lid][0], 'phi1' : node[lid][1], 'lam2' : node[buur][0], 'phi2' : node[buur][1], 'name' : "Interlink: %s --- %s" % (lid, buur), 'desc' : "%s [%s]" % (gformat.showaddr(addr), link_type[addr]), 'style' : "%s%s" % (color, weight), }) f.write(""" """) f.close() if __name__ == "__main__": make_graph()