Handle slice table update upon creation of a job.
[sfa.git] / sfa / plc / slices.py
index fcef25e..dc31793 100644 (file)
@@ -1,6 +1,6 @@
 from types import StringTypes
 from collections import defaultdict
-
+import sys
 from sfa.util.xrn import get_leaf, get_authority, urn_to_hrn
 from sfa.util.plxrn import hrn_to_pl_slicename
 from sfa.util.policy import Policy
@@ -135,19 +135,19 @@ class Slices:
         # slice belongs to out local plc or a myplc peer. We will assume it 
         # is a local site, unless we find out otherwise  
         peer = None
-
+        print>>sys.stderr, " \r\n \r\n \t slices.py get_peer slice_authority  "
         # get this slice's authority (site)
         slice_authority = get_authority(hrn)
 
         # get this site's authority (sfa root authority or sub authority)
         site_authority = get_authority(slice_authority).lower()
-
+        print>>sys.stderr, " \r\n \r\n \t slices.py get_peer slice_authority  %s site_authority %s" %(slice_authority,site_authority) 
         # check if we are already peered with this site_authority, if so
-        peers = self.api.driver.GetPeers({}, ['peer_id', 'peername', 'shortname', 'hrn_root'])
-        for peer_record in peers:
-            names = [name.lower() for name in peer_record.values() if isinstance(name, StringTypes)]
-            if site_authority in names:
-                peer = peer_record
+        #peers = self.api.driver.GetPeers({}, ['peer_id', 'peername', 'shortname', 'hrn_root'])
+        #for peer_record in peers:
+            #names = [name.lower() for name in peer_record.values() if isinstance(name, StringTypes)]
+            #if site_authority in names:
+                #peer = peer_record
 
         return peer
 
@@ -184,10 +184,36 @@ class Slices:
         except: 
             self.api.logger.log_exc('Failed to add/remove slice from nodes')
 
+    def free_egre_key(self):
+        used = set()
+        for tag in self.api.driver.GetSliceTags({'tagname': 'egre_key'}):
+                used.add(int(tag['value']))
+
+        for i in range(1, 256):
+            if i not in used:
+                key = i
+                break
+        else:
+            raise KeyError("No more EGRE keys available")
+
+        return str(key)
+
     def verify_slice_links(self, slice, links, aggregate):
         # nodes is undefined here
         if not links:
-            return 
+            return
+
+        slice_tags = []
+        
+        # set egre key
+        slice_tags.append({'name': 'egre_key', 'value': self.free_egre_key()})
+    
+        # set netns
+        slice_tags.append({'name': 'netns', 'value': '1'})
+
+        # set cap_net_admin 
+        # need to update the attribute string?
+        slice_tags.append({'name': 'capabilities', 'value': 'CAP_NET_ADMIN'}) 
         
         for link in links:
             # get the ip address of the first node in the link
@@ -198,7 +224,13 @@ class Slices:
             if1 = aggregate.interfaces[node['interface_ids'][0]]
             ipaddr = if1['ip']
             topo_rspec = VLink.get_topo_rspec(link, ipaddr)
-            self.api.driver.AddSliceTag(slice['name'], 'topo_rspec', str([topo_rspec]), node_id) 
+            # set topo_rspec tag
+            slice_tags.append({'name': 'topo_rspec', 'value': str([topo_rspec]), 'node_id': node_id})
+            # set vini_topo tag
+            slice_tags.append({'name': 'vini_topo', 'value': 'manual', 'node_id': node_id})
+            #self.api.driver.AddSliceTag(slice['name'], 'topo_rspec', str([topo_rspec]), node_id) 
+
+        self.verify_slice_attributes(slice, slice_tags, append=True, admin=True)
                         
         
 
@@ -276,10 +308,12 @@ class Slices:
         return site        
 
     def verify_slice(self, slice_hrn, slice_record, peer, sfa_peer):
-        slicename = hrn_to_pl_slicename(slice_hrn)
-        parts = slicename.split("_")
+        #slicename = hrn_to_pl_slicename(slice_hrn)
+        parts = hrn_to_pl_slicename(slice_hrn).split("_")
         login_base = parts[0]
+        slicename = slice_hrn
         slices = self.api.driver.GetSlices([slicename]) 
+        print>>sys.stderr, " \r\n \r\rn Slices.py verify_slice slicename %s slices %s slice_record %s"%(slicename ,slices, slice_record)
         if not slices:
             slice = {'name': slicename,
                      'url': slice_record.get('url', slice_hrn), 
@@ -302,8 +336,8 @@ class Slices:
                 # unbind from peer so we can modify if necessary. Will bind back later
                 self.api.driver.UnBindObjectFromPeer('slice', slice['slice_id'], peer['shortname'])
                #Update existing record (e.g. expires field) it with the latest info.
-            if slice_record and slice['expires'] != slice_record['expires']:
-                self.api.driver.UpdateSlice( slice['slice_id'], {'expires' : slice_record['expires']})
+            #if slice_record and slice['expires'] != slice_record['expires']:
+                #self.api.driver.UpdateSlice( slice['slice_id'], {'expires' : slice_record['expires']})
        
         return slice
 
@@ -487,9 +521,12 @@ class Slices:
                     except:
                         pass   
 
-    def verify_slice_attributes(self, slice, requested_slice_attributes):
+    def verify_slice_attributes(self, slice, requested_slice_attributes, append=False, admin=False):
         # get list of attributes users ar able to manage
-        slice_attributes = self.api.driver.GetTagTypes({'category': '*slice*', '|roles': ['user']})
+        filter = {'category': '*slice*'}
+        if not admin:
+            filter['|roles'] = ['user']
+        slice_attributes = self.api.driver.GetTagTypes(filter)
         valid_slice_attribute_names = [attribute['tagname'] for attribute in slice_attributes]
 
         # get sliver attributes
@@ -514,7 +551,7 @@ class Slices:
                         attribute_found=True
                         break
 
-            if not attribute_found:
+            if not attribute_found and not append:
                 removed_slice_attributes.append(slice_tag)
         
         # get attributes that should be added: