# $Id$ # $URL$ """ Scan the VINI Central database and create topology "rspec" attributes for slices that have an EGRE key. This script to be run from a cron job. """ import string import socket from topology import links def get_adjacency_matrix(links): topo = {} for (a, b) in links: aNodes = get_sitenodes(a) bNodes = get_sitenodes(b) for nodeA in aNodes: for nodeB in bNodes: if nodeA not in topo: topo[nodeA] = {} if nodeB not in topo: topo[nodeB] = {} topo[nodeA][nodeB] = 1 topo[nodeB][nodeA] = 1 return topo def get_site(nodeid): if nodes[nodeid]: return nodes[nodeid]['site_id'] raise Exception("Nodeid %s not found." % nodeid) def get_ipaddr(nodeid): if nodes[nodeid]: return socket.gethostbyname(nodes[nodeid]['hostname']) raise Exception("Nodeid %s not found." % nodeid) def get_sitenodes(siteid): if sites[siteid]: return sites[siteid]['node_ids'] raise Exception("Siteid %s not found." % siteid) """ Find the IP address assigned to a virtual interface in the topology (for creating /etc/hosts). Each virtual link is on a /30 subnet. """ def get_linkid(myid, remoteid): if myid < remoteid: linkid = (myid<<7) + remoteid else: linkid = (remoteid<<7) + myid return linkid def get_nodeid(myid, remoteid): if myid < remoteid: nodeid = 1 else: nodeid = 2 return nodeid def get_virt_ip(myid, remoteid): linkid = get_linkid(myid, remoteid) nodeid = get_nodeid(myid, remoteid) first = linkid >> 6 second = ((linkid & 0x3f)<<2) + nodeid return "192.168.%d.%d" % (first, second) def get_virt_net(myid, remoteid): linkid = get_linkid(myid, remoteid) first = linkid >> 6 second = (linkid & 0x3f)<<2 return "192.168.%d.%d/30" % (first, second) """ Create a dictionary of site records keyed by site ID """ def get_sites(): tmp = [] for site in GetSites(): t = site['site_id'], site tmp.append(t) return dict(tmp) """ Create a dictionary of node records keyed by node ID """ def get_nodes(): tmp = [] for node in GetNodes(): t = node['node_id'], node tmp.append(t) return dict(tmp) # For debugging dryrun = 1 """ Need global topology information """ sites = get_sites() nodes = get_nodes() adj_matrix = get_adjacency_matrix(links) for slice in GetSlices(): # Create dictionary of the slice's attributes attrs ={} topo_attr = {} for attribute in GetSliceAttributes(slice['slice_attribute_ids']): attrs[attribute['name']] = attribute['slice_attribute_id'] if attribute['name'] == 'topo_rspec' and attribute['node_id']: topo_attr[attribute['node_id']] = attribute['slice_attribute_id'] if dryrun and slice['name'] == 'pl_trellis': attrs['egre_key'] = 101 if 'egre_key' in attrs: #print "Virtual topology for %s:" % slice['name'] slicenodes = set(slice['node_ids']) hosts = "127.0.0.1\t\tlocalhost\n" """ For each node in the slice, check whether there are any adjacent nodes also in the sliceset using the adjacency matrix. For each pair of adjacent nodes, add to nodes' rspecs. """ topo = {} for a in slicenodes: for b in adj_matrix[a]: if b in slicenodes: if a not in topo: topo[a] = [] my_ip = get_virt_ip(a, b) remote_ip = get_virt_ip(b, a) net = get_virt_net(a, b) link = b, get_ipaddr(b), "1Mbit", my_ip, remote_ip, net topo[a].append(link) shortname = nodes[a]['hostname'].replace('.vini-veritas.net', '') hosts += "%s\t\t%s\n" % (my_ip, shortname) for node in topo: topo_str = "%s" % topo[node] if dryrun: print node, topo_str elif node in topo_attr: UpdateSliceAttribute(topo_attr[node], topo_str) del topo_attr[node] else: id = slice['slice_id'] AddSliceAttribute(id, 'topo_rspec', topo_str, node) if dryrun: print hosts elif 'hosts' in attrs: UpdateSliceAttribute(attrs['hosts'], hosts) else: id = slice['slice_id'] AddSliceAttribute(id, 'hosts', hosts) else: if dryrun: print "No EGRE key for %s" % slice['name'] # Remove old topo_rspec entries if not dryrun: for node in topo_attr: DeleteSliceAttribute(topo_attr[node])