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']
99 def get_tag(self, tagname, slicetags):
100 if tagname not in self.attrs:
101 for i in self.slice_tag_ids:
102 if slicetags[i].tagname == tagname:
103 self.attrs[tagname] = slicetags[i]
106 self.attrs[tagname] = None
107 return self.attrs[tagname]
109 def get_nodes(self, nodes):
111 for id in self.node_ids:
115 def get_rspec(self, slicetags, node):
116 for i in self.slice_tag_ids:
118 if tag.tagname == 'topo_rspec' and node.id == tag.node_id:
126 def __init__(self, tag):
127 self.id = tag['slice_tag_id']
128 self.slice_id = tag['slice_id']
129 self.tagname = tag['tagname']
130 self.value = tag['value']
131 self.node_id = tag['node_id']
138 Create a dictionary of site objects keyed by site ID
142 for site in GetSites():
143 t = site['site_id'], Site(site)
149 Create a dictionary of node objects keyed by node ID
153 for node in GetNodes():
154 t = node['node_id'], Node(node)
159 Create a dictionary of slice objects keyed by slice ID
163 for slice in GetSlices():
164 t = slice['slice_id'], Slice(slice)
169 Create a dictionary of slicetag objects keyed by slice tag ID
171 def get_slice_tags():
173 for tag in GetSliceTags():
174 t = tag['slice_tag_id'], Slicetag(tag)
184 slices = get_slices()
185 slicetags = get_slice_tags()
189 sites[a].add_adjacency(sites[b])
190 sites[b].add_adjacency(sites[a])
194 tag = slice.get_tag('vini_topo', slicetags)
196 topo_type = tag.value
200 if topo_type == 'vsys' or topo_type == 'iias':
202 Assign EGRE key to the slice if needed
203 If no 'netns' attribute, add netns/1
204 For 'vsys', add vsys/setup-link and vsys/setup-nat
207 if slice.get_tag('egre_key', slicetags) and topo_type == 'iias':
209 print "Virtual topology for %s:" % slice.name
211 hosts = "127.0.0.1\t\tlocalhost\n"
213 For each node in the slice, check whether the slice is running on any
214 adjacent nodes. For each pair of adjacent nodes, add to nodes' rspecs.
216 for node in slice.get_nodes(nodes):
218 adj_nodes = node.adjacent_nodes(sites, nodes, slice.node_ids)
219 for adj in adj_nodes:
221 hosts += "%s\t\t%s\n" % (node.get_virt_ip(adj), node.shortname)
223 old_rspec = slice.get_rspec(slicetags, node)
225 topo_str = "%s" % node.rspecs
228 old_rspec.updated = 1
231 if old_rspec and old_rspec.value == topo_str:
232 topo_str = "no change"
235 UpdateSliceTag(old_rspec.id, topo_str)
237 AddSliceTag(slice.id, 'topo_rspec', topo_str, node.id)
242 print "[%s] rspec for %s: %s" % (id, node.shortname, topo_str)
244 hosttag = slice.get_tag('hosts', slicetags)
247 if hosttag and hosts == hosttag.value:
248 hosts = "/etc/hosts: no change"
251 UpdateSliceTag(hosttag.id, hosts)
253 AddSliceTag(slice.id, 'hosts', hosts)
260 print "Slice %s not using IIAS" % slice.name
262 # Remove old topo_rspec entries
265 if (tag.tagname == 'topo_rspec' or tag.tagname == 'hosts') and not tag.updated:
267 slice = slices[tag.slice_id].name
268 node = nodes[tag.node_id].hostname
269 print "Deleting topo_rspec tag %s (%s, %s)" % (tag.id, slice, node)
271 DeleteSliceTag(tag.id)