Modify slice tag handling
authorAndy Bavier <acb@cs.princeton.edu>
Tue, 9 Feb 2010 15:30:24 +0000 (15:30 +0000)
committerAndy Bavier <acb@cs.princeton.edu>
Tue, 9 Feb 2010 15:30:24 +0000 (15:30 +0000)
sfa/managers/vini/vini_network.py
sfa/plc/network.py

index 6529ff1..3a2d54a 100644 (file)
@@ -154,19 +154,20 @@ class ViniSite(Site):
 
 class ViniSlice(Slice):
     def assign_egre_key(self):
-        if not self.get_tag('egre_key'):
+        tag = self.get_tag('egre_key')
+        if not tag:
             try:
                 key = free_egre_key()
-                self.update_tag('egre_key', key)
             except:
                 # Should handle this case...
-                pass
+                raise Error("ran out of EGRE keys!")
+            tag = self.update_tag('egre_key', key)
         return
             
     def turn_on_netns(self):
         tag = self.get_tag('netns')
         if (not tag) or (tag.value != '1'):
-            self.update_tag('netns', '1')
+            tag = self.update_tag('netns', '1')
         return
    
     def turn_off_netns(self):
@@ -181,12 +182,13 @@ class ViniSlice(Slice):
             caps = tag.value.split(',')
             for cap in caps:
                 if cap == "CAP_NET_ADMIN":
-                    return
+                    newcaps = tag.value
+                    break
             else:
                 newcaps = "CAP_NET_ADMIN," + tag.value
-                self.update_tag('capabilities', newcaps)
+            self.update_tag('capabilities', newcaps)
         else:
-            self.add_tag('capabilities', 'CAP_NET_ADMIN')
+            tag = self.add_tag('capabilities', 'CAP_NET_ADMIN')
         return
     
     def remove_cap_net_admin(self):
@@ -204,23 +206,6 @@ class ViniSlice(Slice):
                 tag.delete()
         return
 
-    # Update the vsys/setup-link and vsys/setup-nat slice tags.
-    def add_vsys_tags(self):
-        link = nat = False
-        for tag in self.network.getSliceTags():
-            if tag.tagname == 'vsys':
-                if tag.value == 'setup-link':
-                    link = True
-                elif tag.value == 'setup-nat':
-                    nat = True
-        if not link:
-            self.add_tag('vsys', 'setup-link')
-        if not nat:
-            self.add_tag('vsys', 'setup-nat')
-        return
-
-
-
 class Link:
     def __init__(self, end1, end2, bps = 1000 * 1000000, parent = None):
         self.end1 = end1
@@ -387,18 +372,23 @@ class ViniNetwork(Network):
     def updateSliceTags(self):
         slice = self.slice
 
-        slice.update_tag('vini_topo', 'manual')
+        tag = slice.update_tag('vini_topo', 'manual')
         slice.assign_egre_key()
         slice.turn_on_netns()
         slice.add_cap_net_admin()
 
-        for node in slice.get_nodes():
+        for node in self.nodesWithSlivers():
             linkdesc = []
             for link in node.links:
                 linkdesc.append(node.get_topo_rspec(link))
             if linkdesc:
                 topo_str = "%s" % linkdesc
-                slice.update_tag('topo_rspec', topo_str, node)
+                tag = slice.update_tag('topo_rspec', topo_str, node)
+
+        # Update or expire the topo_rspec tags
+        for tag in self.getSliceTags():
+            if tag.tagname in ['topo_rspec']:
+                tag.writable = True
 
         Network.updateSliceTags(self)
 
index 7974e3a..1c204ce 100644 (file)
@@ -146,8 +146,9 @@ class Slice:
         return n
   
     # Add a new slice tag   
-    def add_tag(self, tagname, value, node = None):
-        record = {'slice_tag_id':None, 'slice_id':self.id, 'tagname':tagname, 'value':value}
+    def add_tag(self, tagname, value, node = None, category = 'slice/rspec'):
+        record = {'slice_tag_id':None, 'slice_id':self.id, 'tagname':tagname, 'value':value, 
+                  'category':category}
         if node:
             record['node_id'] = node.id
         else:
@@ -157,6 +158,7 @@ class Slice:
         self.slice_tag_ids.append(tag.id)
         tag.changed = True       
         tag.updated = True
+        tag.writable = True
         return tag
     
     # Update a slice tag if it exists, else add it             
@@ -170,6 +172,8 @@ class Slice:
         else:
             tag = self.add_tag(tagname, value, node)
         tag.updated = True
+        tag.writable = True
+        return tag
             
     def update_multi_tag(self, tagname, value, node = None):
         tags = self.get_multi_tag(tagname, node)
@@ -180,20 +184,23 @@ class Slice:
         else:
             tag = self.add_tag(tagname, value, node)
         tag.updated = True
+        tag.writable = True
+        return tag
             
     def tags_to_xml(self, xml, node = None):
         tagtypes = self.network.getTagTypes()
         for tt in tagtypes:
-            if tt.multi:
-                tags = self.get_multi_tag(tt.tagname, node)
-                for tag in tags:
-                    if not tag.deleted:  ### Debugging
-                        xml << (tag.tagname, tag.value)
-            else:
-                tag = self.get_tag(tt.tagname, node)
-                if tag:
-                    if not tag.deleted:   ### Debugging
-                        xml << (tag.tagname, tag.value)
+            if tt.in_rspec:
+                if tt.multi:
+                    tags = self.get_multi_tag(tt.tagname, node)
+                    for tag in tags:
+                        if not tag.deleted:  ### Debugging
+                            xml << (tag.tagname, tag.value)
+                else:
+                    tag = self.get_tag(tt.tagname, node)
+                    if tag:
+                        if not tag.deleted:   ### Debugging
+                            xml << (tag.tagname, tag.value)
 
     def toxml(self, xml):
         with xml.sliver_defaults:
@@ -212,16 +219,23 @@ class Slicetag:
         self.tagname = tag['tagname']
         self.value = tag['value']
         self.node_id = tag['node_id']
+        self.category = tag['category']
         self.updated = False
         self.changed = False
         self.deleted = False
-    
+        self.writable = False
+        if self.category == 'slice/rspec':
+            self.writable = True
+        
     # Mark a tag as deleted
     def delete(self):
         self.deleted = True
         self.updated = True
     
     def write(self, api):
+        if not self.writable:
+            return
+
         if self.changed:
             if int(self.id) > 0:
                 api.plshell.UpdateSliceTag(api.plauth, self.id, self.value)
@@ -235,11 +249,14 @@ class Slicetag:
 class TagType:
     def __init__(self, tagtype):
         self.id = tagtype['tag_type_id']
+        self.category = tagtype['category']
         self.tagname = tagtype['tagname']
+        self.multi = False
+        self.in_rspec = False
+        if self.category == 'slice/rspec':
+            self.in_rspec = True
         if self.tagname in ['codemux', 'ip_addresses', 'vsys']:
             self.multi = True
-        else:
-            self.multi = False
 
 
 """
@@ -353,13 +370,14 @@ class Network:
         # Do we need to check caller's role before update???
         tagtypes = self.getTagTypes()
         for tt in tagtypes:
-            if tt.multi:
-                for e in element.iterfind("./" + tt.tagname):
-                    self.slice.update_multi_tag(tt.tagname, e.text, node)
-            else:
-                e = element.find("./" + tt.tagname)
-                if e is not None:
-                    self.slice.update_tag(tt.tagname, e.text, node)
+            if tt.in_rspec:
+                if tt.multi:
+                    for e in element.iterfind("./" + tt.tagname):
+                        self.slice.update_multi_tag(tt.tagname, e.text, node)
+                else:
+                    e = element.find("./" + tt.tagname)
+                    if e is not None:
+                        self.slice.update_tag(tt.tagname, e.text, node)
 
     """
     Annotate the objects in the Network with information from the RSpec
@@ -502,9 +520,8 @@ class Network:
     def get_tag_types(self, api):
         tmp = []
         for tag in api.plshell.GetTagTypes(api.plauth):
-            if tag['category'] == 'slice/rspec':
-                t = tag['tagname'], TagType(tag)
-                tmp.append(t)
+            t = tag['tagname'], TagType(tag)
+            tmp.append(t)
         return dict(tmp)
     
     """