Decided to make this an API call.
[nodemanager-topo.git] / create-topo-attributes.py
1 # $Id$
2 # $URL$
3
4 """
5 Scan the VINI Central database and create topology "rspec" attributes for
6 slices that have an EGRE key.  This script to be run from a cron job.
7 """
8
9 import string
10 import socket
11 from topology import links
12
13
14 def get_adjacency_matrix(links):
15     topo = {}
16     idx = 1
17     for (a, b) in links:
18         aNodes = get_sitenodes(a)
19         bNodes = get_sitenodes(b)
20         for nodeA in aNodes:
21             for nodeB in bNodes:
22                 if nodeA not in topo:
23                     topo[nodeA] = {}
24                 if nodeB not in topo:
25                     topo[nodeB] = {}
26                 topo[nodeA][nodeB] = idx
27                 topo[nodeB][nodeA] = idx
28         idx += 1
29     return topo
30                     
31             
32
33 def get_site(nodeid):
34     if nodes[nodeid]:
35         return nodes[nodeid]['site_id']
36     raise Exception("Nodeid %s not found." % nodeid)
37
38
39 def get_ipaddr(nodeid):
40     if nodes[nodeid]:
41         return socket.gethostbyname(nodes[nodeid]['hostname'])
42     raise Exception("Nodeid %s not found." % nodeid)
43
44
45 def get_sitenodes(siteid):
46     if sites[siteid]:
47         return sites[siteid]['node_ids']
48     raise Exception("Siteid %s not found." % siteid)
49
50
51 """
52 Find the IP address assigned to a virtual interface in the topology
53 (for creating /etc/hosts)
54 """
55 def get_virt_ip(myid, linkid):
56     return "192.168.%d.%d" % (linkid, myid)
57
58 def get_virt_net(linkid):
59     return "192.168.%d.0/24" % linkid
60
61 """
62 Create a dictionary of site records keyed by site ID
63 """
64 def get_sites():
65     tmp = []
66     for site in GetSites():
67         t = site['site_id'], site
68         tmp.append(t)
69     return dict(tmp)
70
71
72 """
73 Create a dictionary of node records keyed by node ID
74 """
75 def get_nodes():
76     tmp = []
77     for node in GetNodes():
78         t = node['node_id'], node
79         tmp.append(t)
80     return dict(tmp)
81
82
83 # For debugging
84 dryrun = 1
85
86 """ Need global topology information """
87 sites = get_sites()
88 nodes = get_nodes()
89
90 adj_matrix = get_adjacency_matrix(links)
91
92 for slice in GetSlices():
93     # Create dictionary of the slice's attributes 
94     attrs ={}
95     topo_attr = {}
96     for attribute in GetSliceAttributes(slice['slice_attribute_ids']):
97         attrs[attribute['name']] = attribute['slice_attribute_id']
98         if attribute['name'] == 'topo_rspec' and attribute['node_id']:
99             topo_attr[attribute['node_id']] = attribute['slice_attribute_id']
100             
101     if dryrun and slice['name'] == 'pl_trellis':
102         attrs['egre_key'] = 101
103         
104     if 'egre_key' in attrs:
105         #print "Virtual topology for %s:" % slice['name']
106         slicenodes = set(slice['node_ids'])
107         hosts = "127.0.0.1\t\tlocalhost\n"
108         """
109         For each node in the slice, check whether there are any adjacent
110         nodes also in the sliceset using the adjacency matrix.
111         For each pair of adjacent nodes, add to nodes' rspecs.
112         """
113         topo = {}
114         for a in slicenodes:
115             for b in adj_matrix[a]:
116                 if b in slicenodes:
117                     if a not in topo:
118                         topo[a] = []
119                     link_id = adj_matrix[a][b]
120                     my_ip = get_virt_ip(a, link_id)
121                     remote_ip = get_virt_ip(b, link_id)
122                     net = get_virt_net(link_id)
123                     link = b, get_ipaddr(b), "1Mbit", my_ip, remote_ip, net
124                     topo[a].append(link)
125                     shortname = nodes[a]['hostname'].replace('.vini-veritas.net', '')
126                     hosts += "%s\t\t%s\n" % (my_ip, shortname)
127
128         for node in topo:
129             topo_str = "%s" % topo[node]
130             if dryrun:
131                 print node, topo_str
132             elif node in topo_attr:
133                 UpdateSliceAttribute(topo_attr[node], topo_str)
134                 del topo_attr[node]
135             else:
136                 id = slice['slice_id']
137                 AddSliceAttribute(id, 'topo_rspec', topo_str, node)
138
139         if dryrun:
140             print hosts
141         elif 'hosts' in attrs:
142             UpdateSliceAttribute(attrs['hosts'], hosts)
143         else:
144             id = slice['slice_id']
145             AddSliceAttribute(id, 'hosts', hosts)
146     else:
147         if dryrun:
148             print "No EGRE key for %s" % slice['name']
149
150     # Remove old topo_rspec entries
151     
152     if not dryrun:
153         for node in topo_attr:
154             DeleteSliceAttribute(topo_attr[node])
155
156