Connection marking for NAT
[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     for (a, b) in links:
17         aNodes = get_sitenodes(a)
18         bNodes = get_sitenodes(b)
19         for nodeA in aNodes:
20             for nodeB in bNodes:
21                 if nodeA not in topo:
22                     topo[nodeA] = {}
23                 if nodeB not in topo:
24                     topo[nodeB] = {}
25                 topo[nodeA][nodeB] = 1
26                 topo[nodeB][nodeA] = 1
27     return topo
28                     
29             
30
31 def get_site(nodeid):
32     if nodes[nodeid]:
33         return nodes[nodeid]['site_id']
34     raise Exception("Nodeid %s not found." % nodeid)
35
36
37 def get_ipaddr(nodeid):
38     if nodes[nodeid]:
39         return socket.gethostbyname(nodes[nodeid]['hostname'])
40     raise Exception("Nodeid %s not found." % nodeid)
41
42
43 def get_sitenodes(siteid):
44     if sites[siteid]:
45         return sites[siteid]['node_ids']
46     raise Exception("Siteid %s not found." % siteid)
47
48
49 """
50 Find the IP address assigned to a virtual interface in the topology
51 (for creating /etc/hosts).
52 Each virtual link is on a /30 subnet.
53 """
54 def get_linkid(myid, remoteid):
55     if myid < remoteid:
56         linkid = (myid<<7) + remoteid
57     else:
58         linkid = (remoteid<<7) + myid
59     return linkid
60
61 def get_nodeid(myid, remoteid):
62     if myid < remoteid:
63         nodeid = 1
64     else:
65         nodeid = 2
66     return nodeid
67
68 def get_virt_ip(myid, remoteid):
69     linkid = get_linkid(myid, remoteid)
70     nodeid = get_nodeid(myid, remoteid)
71     first = linkid >> 6
72     second = ((linkid & 0x3f)<<2) + nodeid
73     return "192.168.%d.%d" % (first, second)
74
75 def get_virt_net(myid, remoteid):
76     linkid = get_linkid(myid, remoteid)
77     first = linkid >> 6
78     second = (linkid & 0x3f)<<2
79     return "192.168.%d.%d/30" % (first, second)
80
81 """
82 Create a dictionary of site records keyed by site ID
83 """
84 def get_sites():
85     tmp = []
86     for site in GetSites():
87         t = site['site_id'], site
88         tmp.append(t)
89     return dict(tmp)
90
91
92 """
93 Create a dictionary of node records keyed by node ID
94 """
95 def get_nodes():
96     tmp = []
97     for node in GetNodes():
98         t = node['node_id'], node
99         tmp.append(t)
100     return dict(tmp)
101
102
103 # For debugging
104 dryrun = 1
105
106 """ Need global topology information """
107 sites = get_sites()
108 nodes = get_nodes()
109
110 adj_matrix = get_adjacency_matrix(links)
111
112 for slice in GetSlices():
113     # Create dictionary of the slice's attributes 
114     attrs ={}
115     topo_attr = {}
116     for attribute in GetSliceAttributes(slice['slice_attribute_ids']):
117         attrs[attribute['name']] = attribute['slice_attribute_id']
118         if attribute['name'] == 'topo_rspec' and attribute['node_id']:
119             topo_attr[attribute['node_id']] = attribute['slice_attribute_id']
120             
121     if dryrun and slice['name'] == 'pl_trellis':
122         attrs['egre_key'] = 101
123         
124     if 'egre_key' in attrs:
125         #print "Virtual topology for %s:" % slice['name']
126         slicenodes = set(slice['node_ids'])
127         hosts = "127.0.0.1\t\tlocalhost\n"
128         """
129         For each node in the slice, check whether there are any adjacent
130         nodes also in the sliceset using the adjacency matrix.
131         For each pair of adjacent nodes, add to nodes' rspecs.
132         """
133         topo = {}
134         for a in slicenodes:
135             for b in adj_matrix[a]:
136                 if b in slicenodes:
137                     if a not in topo:
138                         topo[a] = []
139                     my_ip = get_virt_ip(a, b)
140                     remote_ip = get_virt_ip(b, a)
141                     net = get_virt_net(a, b)
142                     link = b, get_ipaddr(b), "1Mbit", my_ip, remote_ip, net
143                     topo[a].append(link)
144                     shortname = nodes[a]['hostname'].replace('.vini-veritas.net', '')
145                     hosts += "%s\t\t%s\n" % (my_ip, shortname)
146
147         for node in topo:
148             topo_str = "%s" % topo[node]
149             if dryrun:
150                 print node, topo_str
151             elif node in topo_attr:
152                 UpdateSliceAttribute(topo_attr[node], topo_str)
153                 del topo_attr[node]
154             else:
155                 id = slice['slice_id']
156                 AddSliceAttribute(id, 'topo_rspec', topo_str, node)
157
158         if dryrun:
159             print hosts
160         elif 'hosts' in attrs:
161             UpdateSliceAttribute(attrs['hosts'], hosts)
162         else:
163             id = slice['slice_id']
164             AddSliceAttribute(id, 'hosts', hosts)
165     else:
166         if dryrun:
167             print "No EGRE key for %s" % slice['name']
168
169     # Remove old topo_rspec entries
170     
171     if not dryrun:
172         for node in topo_attr:
173             DeleteSliceAttribute(topo_attr[node])
174
175