X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=create-topo-attributes.py;h=78d965eba36ef77ebae2245c2b88aed7bd3e1b91;hb=98fd1c8e1c64e30f39bd5b922d0bc1f762e83ba9;hp=91ae976e0d8d87385f6e2a571c491a3d053e170f;hpb=a161babe00fce7cf62d81f41e3cabc96b43d8297;p=nodemanager-topo.git diff --git a/create-topo-attributes.py b/create-topo-attributes.py index 91ae976..78d965e 100755 --- a/create-topo-attributes.py +++ b/create-topo-attributes.py @@ -8,7 +8,7 @@ slices that have an EGRE key. This script to be run from a cron job. import string import socket -from topology import links +from topology import links, bwlimits class Node: def __init__(self, node): @@ -61,11 +61,11 @@ class Node: def init_rspecs(self): self.rspecs = [] - def add_rspec(self, remote): + def add_rspec(self, remote, bw): my_ip = self.get_virt_ip(remote) remote_ip = remote.get_virt_ip(self) net = self.get_virt_net(remote) - rspec = remote.id, remote.ipaddr, "1Mbit", my_ip, remote_ip, net + rspec = remote.id, remote.ipaddr, bw, my_ip, remote_ip, net self.rspecs.append(rspec) @@ -110,47 +110,86 @@ class Slice: n.append(nodes[id]) return n - - def add_tag(self, tagname, value, slicetags, dryrun, node = None): + + # Add a new slice tag + def add_tag(self, tagname, value, slicetags, node = None): + record = {'slice_tag_id':None, 'slice_id':self.id, 'tagname':tagname, 'value':value} if node: - id = AddSliceTag(self.id, tagname, value, node.id) + record['node_id'] = node.id else: - id = AddSliceTag(self.id, tagname, value) - - record = GetSliceTags([id])[0] + record['node_id'] = None tag = Slicetag(record) - slicetags[id] = tag - self.slice_tag_ids.append(id) - + slicetags[tag.id] = tag + self.slice_tag_ids.append(tag.id) + tag.changed = True + tag.updated = True return tag - - def update_tag(self, tagname, value, slicetags, dryrun, node = None): + + # Update a slice tag if it exists, else add it + def update_tag(self, tagname, value, slicetags, node = None): tag = self.get_tag(tagname, slicetags, node) - if tag and tag.value == value: value = "no change" - elif not dryrun: - if tag: - UpdateSliceTag(tag.id, value) - else: - tag = self.add_tag(tagname, value, slicetags, dryrun, node) - - if tag: - tag.updated = 1 - id = tag.id + elif tag: + tag.value = value + tag.changed = True else: - id = 'new' + tag = self.add_tag(tagname, value, slicetags, node) + tag.updated = True - if dryrun: - if node: - print "[%s] %s: %s (%s)" % (id, tagname, value, node.shortname) + def assign_egre_key(self, slicetags): + if not self.get_tag('egre_key', slicetags): + try: + key = free_egre_key(slicetags) + self.update_tag('egre_key', key, slicetags) + except: + # Should handle this case... + pass + return + + def turn_on_netns(self, slicetags): + tag = self.get_tag('netns', slicetags) + if (not tag) or (tag.value != '1'): + self.update_tag('netns', '1', slicetags) + return + + def turn_off_netns(self, slicetags): + tag = self.get_tag('netns', slicetags) + if tag and (tag.value != '0'): + tag.delete() + return + + def add_cap_net_admin(self, slicetags): + tag = self.get_tag('capabilities', slicetags) + if tag: + caps = tag.value.split(',') + for cap in caps: + if cap == "CAP_NET_ADMIN": + return + else: + newcaps = "CAP_NET_ADMIN," + tag.value + self.update_tag('capabilities', newcaps, slicetags) + else: + self.add_tag('capabilities', 'CAP_NET_ADMIN', slicetags) + return + + def remove_cap_net_admin(self, slicetags): + tag = self.get_tag('capabilities', slicetags) + if tag: + caps = tag.value.split(',') + newcaps = [] + for cap in caps: + if cap != "CAP_NET_ADMIN": + newcaps.append(cap) + if newcaps: + value = ','.join(newcaps) + self.update_tag('capabilities', value, slicetags) else: - print "[%s] %s: %s" % (id, tagname, value) + tag.delete() + return - """ - Update the vsys/setup-link and vsys/setup-nat slice tags. - """ - def add_vsys_tags(self, slicetags, dryrun): + # Update the vsys/setup-link and vsys/setup-nat slice tags. + def add_vsys_tags(self, slicetags): link = nat = False for i in self.slice_tag_ids: tag = slicetags[i] @@ -160,21 +199,64 @@ class Slice: elif tag.value == 'setup-nat': nat = True if not link: - self.add_tag('vsys', 'setup-link', slicetags, dryrun) + self.add_tag('vsys', 'setup-link', slicetags) if not nat: - self.add_tag('vsys', 'setup-nat', slicetags, dryrun) + self.add_tag('vsys', 'setup-nat', slicetags) + return + class Slicetag: + newid = -1 def __init__(self, tag): self.id = tag['slice_tag_id'] + if not self.id: + # Make one up for the time being... + self.id = Slicetag.newid + Slicetag.newid -= 1 self.slice_id = tag['slice_id'] self.tagname = tag['tagname'] self.value = tag['value'] self.node_id = tag['node_id'] - self.updated = 0 - - - + self.updated = False + self.changed = False + self.deleted = False + + # Mark a tag as deleted + def delete(self): + self.deleted = True + self.updated = True + + def write(self, slices, nodes, dryrun): + if not dryrun: + if self.changed: + if int(self.id) > 0: + UpdateSliceTag(self.id, self.value) + else: + AddSliceTag(self.slice_id, self.tagname, self.value, self.node_id) + elif self.deleted and int(self.id) > 0: + try: + DeleteSliceTag(self.id) + except: + print "[%s] %s: could not delete" % (self.id, self.tagname) + else: + try: + slice = slices[self.slice_id].name + except: + return + if self.node_id: + node = nodes[tag.node_id].hostname + if self.updated: + if self.deleted: + self.value = "deleted" + elif not self.changed: + self.value = "no change" + if int(self.id) < 0: + self.id = "new" + if self.node_id: + print "[%s] %s: %s (%s, %s)" % (self.id, self.tagname, self.value, slice, node) + else: + print "[%s] %s: %s (%s)" % (self.id, self.tagname, self.value, slice) + """ Create a dictionary of site objects keyed by site ID @@ -221,8 +303,8 @@ def get_slice_tags(): Find a free EGRE key """ def free_egre_key(slicetags): + used = set() for i in slicetags: - used = set() tag = slicetags[i] if tag.tagname == 'egre_key': used.add(int(tag.value)) @@ -257,26 +339,35 @@ for i in slices: else: topo_type = None - if topo_type == 'vsys' or topo_type == 'iias': - """ - Assign EGRE key to the slice if needed - If no 'netns' attribute, add netns/1 - For 'vsys', add vsys/setup-link and vsys/setup-nat - """ - if not slice.get_tag('egre_key', slicetags): - key = free_egre_key(slicetags) - slice.update_tag('egre_key', key, slicetags, dryrun) + """ + Valid values of topo_type: + 'vsys': Use vsys topology scripts to set up virtual links + 'iias': Automatically create a virtual topology mirroring the physical one + 'manual': Don't modify the topo_rspec tags if present + None: No virtual topology + """ + if topo_type in ['vsys', 'iias', 'manual']: + slice.assign_egre_key(slicetags) + slice.turn_on_netns(slicetags) + slice.add_cap_net_admin(slicetags) + else: + # Let them keep EGRE key for now... + slice.turn_off_netns(slicetags) + slice.remove_cap_net_admin(slicetags) + # Add vsys/setup-link and vsys/setup-nat if topo_type == 'vsys' and slice.get_tag('egre_key', slicetags): - slice.add_vsys_tags(slicetags, dryrun) + slice.add_vsys_tags(slicetags) if topo_type == 'iias' and slice.get_tag('egre_key', slicetags): if dryrun: - print "Virtual topology for %s:" % slice.name - - if not slice.get_tag('netns', slicetags): - slice.update_tag('netns', '1', slicetags, dryrun) + print "Building virtual topology for %s" % slice.name + if slice.name in bwlimits: + bw = bwlimits[slice.name] + else: + bw = "1Mbit" + hosts = "127.0.0.1\t\tlocalhost\n" """ For each node in the slice, check whether the slice is running on any @@ -286,30 +377,28 @@ for i in slices: node.init_rspecs() adj_nodes = node.adjacent_nodes(sites, nodes, slice.node_ids) for adj in adj_nodes: - node.add_rspec(adj) + node.add_rspec(adj, bw) hosts += "%s\t\t%s\n" % (node.get_virt_ip(adj), node.shortname) if node.rspecs: topo_str = "%s" % node.rspecs - slice.update_tag('topo_rspec', topo_str, slicetags, dryrun, node) + slice.update_tag('topo_rspec', topo_str, slicetags, node) - slice.update_tag('hosts', hosts, slicetags, dryrun) + slice.update_tag('hosts', hosts, slicetags) else: if dryrun: print "Slice %s not using IIAS" % slice.name -# Remove old topo_rspec entries + if topo_type == 'manual' and slice.get_tag('egre_key', slicetags): + for node in slice.get_nodes(nodes): + topo_tag = slice.get_tag('topo_rspec', slicetags, node) + if topo_tag: + topo_tag.updated = True + +# Update the tag values in the database for i in slicetags: tag = slicetags[i] if (tag.tagname == 'topo_rspec' or tag.tagname == 'hosts') and not tag.updated: - if dryrun: - slice = slices[tag.slice_id].name - if tag.node_id: - node = nodes[tag.node_id].hostname - print "Deleting tag %s (%s, %s)" % (tag.id, slice, node) - else: - print "Deleting tag %s (%s)" % (tag.id, slice) - - else: - DeleteSliceTag(tag.id) + tag.delete() + tag.write(slices, nodes, dryrun)