5 Scan the VINI Central database and create topology "rspec" tags for
6 slices that have an EGRE key. This script to be run from a cron job.
11 from topology import links
14 def __init__(self, node):
15 self.id = node['node_id']
16 self.hostname = node['hostname']
17 self.shortname = self.hostname.replace('.vini-veritas.net', '')
18 self.site_id = node['site_id']
19 self.ipaddr = socket.gethostbyname(self.hostname)
21 def get_link_id(self, remote):
22 if self.id < remote.id:
23 link = (self.id<<7) + remote.id
25 link = (remote.id<<7) + self.id
28 def get_iface_id(self, remote):
29 if self.id < remote.id:
35 def get_virt_ip(self, remote):
36 link = self.get_link_id(remote)
37 iface = self.get_iface_id(remote)
39 second = ((link & 0x3f)<<2) + iface
40 return "192.168.%d.%d" % (first, second)
42 def get_virt_net(self, remote):
43 link = self.get_link_id(remote)
45 second = (link & 0x3f)<<2
46 return "192.168.%d.%d/30" % (first, second)
48 def get_site(self, sites):
49 return sites[self.site_id]
52 # What nodes in the set of node_ids are adjacent to this one?
53 def adjacent_nodes(self, sites, nodes, node_ids):
54 mysite = self.get_site(sites)
55 adj_ids = mysite.adj_node_ids.intersection(node_ids)
58 adj_nodes.append(nodes[id])
61 def init_rspecs(self):
64 def add_rspec(self, remote):
65 my_ip = self.get_virt_ip(remote)
66 remote_ip = remote.get_virt_ip(self)
67 net = self.get_virt_net(remote)
68 rspec = remote.id, remote.ipaddr, "1Mbit", my_ip, remote_ip, net
69 self.rspecs.append(rspec)
73 def __init__(self, site):
74 self.id = site['site_id']
75 self.node_ids = site['node_ids']
76 self.adj_site_ids = set()
77 self.adj_node_ids = set()
79 def get_sitenodes(self, nodes):
81 for i in self.node_ids:
85 def add_adjacency(self, site):
86 self.adj_site_ids.add(site.id)
87 for n in site.node_ids:
88 self.adj_node_ids.add(n)
92 def __init__(self, slice):
93 self.id = slice['slice_id']
94 self.name = slice['name']
95 self.node_ids = set(slice['node_ids'])
96 self.slice_tag_ids = slice['slice_tag_ids']
98 def get_tag(self, tagname, slicetags, node = None):
99 for i in self.slice_tag_ids:
101 if tag.tagname == tagname:
102 if (not node) or (node.id == tag.node_id):
107 def get_nodes(self, nodes):
109 for id in self.node_ids:
114 def add_tag(self, tagname, value, slicetags, dryrun, node = None):
116 id = AddSliceTag(self.id, tagname, value, node.id)
118 id = AddSliceTag(self.id, tagname, value)
120 record = GetSliceTags([id])[0]
121 tag = Slicetag(record)
123 self.slice_tag_ids.append(id)
127 def update_tag(self, tagname, value, slicetags, dryrun, node = None):
128 tag = self.get_tag(tagname, slicetags, node)
130 if tag and tag.value == value:
134 UpdateSliceTag(tag.id, value)
136 tag = self.add_tag(tagname, value, slicetags, dryrun, node)
146 print "[%s] %s: %s (%s)" % (id, tagname, value, node.shortname)
148 print "[%s] %s: %s" % (id, tagname, value)
151 Update the vsys/setup-link and vsys/setup-nat slice tags.
153 def add_vsys_tags(self, slicetags, dryrun):
155 for i in self.slice_tag_ids:
157 if tag.tagname == 'vsys':
158 if tag.value == 'setup-link':
160 elif tag.value == 'setup-nat':
163 self.add_tag('vsys', 'setup-link', slicetags, dryrun)
165 self.add_tag('vsys', 'setup-nat', slicetags, dryrun)
168 def __init__(self, tag):
169 self.id = tag['slice_tag_id']
170 self.slice_id = tag['slice_id']
171 self.tagname = tag['tagname']
172 self.value = tag['value']
173 self.node_id = tag['node_id']
180 Create a dictionary of site objects keyed by site ID
184 for site in GetSites():
185 t = site['site_id'], Site(site)
191 Create a dictionary of node objects keyed by node ID
195 for node in GetNodes():
196 t = node['node_id'], Node(node)
201 Create a dictionary of slice objects keyed by slice ID
205 for slice in GetSlices():
206 t = slice['slice_id'], Slice(slice)
211 Create a dictionary of slicetag objects keyed by slice tag ID
213 def get_slice_tags():
215 for tag in GetSliceTags():
216 t = tag['slice_tag_id'], Slicetag(tag)
223 def free_egre_key(slicetags):
227 if tag.tagname == 'egre_key':
228 used.add(int(tag.value))
230 for i in range(1, 256):
235 raise KeyError("No more EGRE keys available")
244 slices = get_slices()
245 slicetags = get_slice_tags()
249 sites[a].add_adjacency(sites[b])
250 sites[b].add_adjacency(sites[a])
254 tag = slice.get_tag('vini_topo', slicetags)
256 topo_type = tag.value
260 if topo_type == 'vsys' or topo_type == 'iias':
262 Assign EGRE key to the slice if needed
263 If no 'netns' attribute, add netns/1
264 For 'vsys', add vsys/setup-link and vsys/setup-nat
266 if not slice.get_tag('egre_key', slicetags):
267 key = free_egre_key(slicetags)
268 slice.update_tag('egre_key', key, slicetags, dryrun)
270 if topo_type == 'vsys' and slice.get_tag('egre_key', slicetags):
271 slice.add_vsys_tags(slicetags, dryrun)
273 if topo_type == 'iias' and slice.get_tag('egre_key', slicetags):
275 print "Virtual topology for %s:" % slice.name
277 if not slice.get_tag('netns', slicetags):
278 slice.update_tag('netns', '1', slicetags, dryrun)
280 hosts = "127.0.0.1\t\tlocalhost\n"
282 For each node in the slice, check whether the slice is running on any
283 adjacent nodes. For each pair of adjacent nodes, add to nodes' rspecs.
285 for node in slice.get_nodes(nodes):
287 adj_nodes = node.adjacent_nodes(sites, nodes, slice.node_ids)
288 for adj in adj_nodes:
290 hosts += "%s\t\t%s\n" % (node.get_virt_ip(adj), node.shortname)
292 topo_str = "%s" % node.rspecs
293 slice.update_tag('topo_rspec', topo_str, slicetags, dryrun, node)
295 slice.update_tag('hosts', hosts, slicetags, dryrun)
298 print "Slice %s not using IIAS" % slice.name
300 # Remove old topo_rspec entries
303 if (tag.tagname == 'topo_rspec' or tag.tagname == 'hosts') and not tag.updated:
305 slice = slices[tag.slice_id].name
307 node = nodes[tag.node_id].hostname
308 print "Deleting tag %s (%s, %s)" % (tag.id, slice, node)
310 print "Deleting tag %s (%s)" % (tag.id, slice)
313 DeleteSliceTag(tag.id)