#!/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 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() CACHE_FILE = '/tmp/rd2etrs.yaml' coordinates = None def rd2etrs(xrd, yrd, hnap=0.0): """ Convert rd to etrs """ global coordinates if coordinates == None: try: coordinates = get_yaml(CACHE_FILE) if coordinates.has_key((xrd, yrd)): return coordinates[(xrd, yrd)] except (IOError,AttributeError): coordinates = dict() pass item = dict() item['xrd'] = xrd item['yrd'] = yrd item['hnap'] = hnap f = urllib.urlopen('http://www.rdnap.nl/cgi-bin/rdetrs.pl?func=rd2etrs&xrd=%(xrd)s&yrd=%(yrd)s&hnap=%(hnap)s' % item) raw = f.read() r = re.compile('name="([a-z_]+)" value="([0-9\.]+)"') for i in r.finditer(raw): name, value = i.group(1,2) value = float(value) item[name] = value lam = item['lam_deg'] + (item['lam_min'] + (item['lam_sec'] / 60)) / 60 phi = item['phi_deg'] + (item['phi_min'] + (item['phi_sec'] / 60)) / 60 coordinates[(xrd, yrd)] = (phi, lam) write_yaml(CACHE_FILE, coordinates) return (lam, phi) OUTFILE = 'network.png' def make_graph(): 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_proxylist() + gformat.get_nodelist(): print "## Processing host", host datadump = gformat.get_yaml(host) 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]) lam, phi = rd2etrs(datadump['rdnap_x'], datadump['rdnap_y']) node[host] = (lam, phi) f.write(""" All active nodes Node %(name)s %(desc)s> #node_status_up %(lam)s,%(phi)s,0 """ % {'name' : host, 'desc' : cgi.escape(datadump['location']), '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 link_type[addr] == '11a': color = '#ff0000ff' weight = 2 elif link_type[addr] == 'eth': color = '#ffff0000' weight = 4 else: color = '#ff000000' weight = 1 leden = sorted(set(leden)) for index,lid in enumerate(leden[:-1]): for buur in leden[index + 1:]: 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()