Update all slice tags in one shot
Andy Bavier [Wed, 27 May 2009 20:08:15 +0000 (20:08 +0000)]
create-topo-attributes.py

index 91ae976..925b721 100755 (executable)
@@ -110,47 +110,84 @@ 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)
-        else:
-            id = AddSliceTag(self.id, tagname, value)
-            
-        record = GetSliceTags([id])[0]
+            record['node_id'] = node.id
         tag = Slicetag(record)
         slicetags[id] = tag
         self.slice_tag_ids.append(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," + caps
+                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 +197,58 @@ 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:
+                DeleteSliceTag(self.id)
+        else:
+            slice = slices[self.slice_id].name
+            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
@@ -258,24 +332,21 @@ for i in slices:
         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)
+        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
             
         hosts = "127.0.0.1\t\tlocalhost\n"
         """
@@ -290,26 +361,18 @@ for i in slices:
                 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
+# 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)