Better mgt of external slices/users/sites + fixes
[sfa.git] / sfa / planetlab / plaggregate.py
index 1fd3591..e147041 100644 (file)
@@ -1,5 +1,5 @@
 #!/usr/bin/python
-from sfa.util.xrn import Xrn, hrn_to_urn, urn_to_hrn
+from sfa.util.xrn import Xrn, hrn_to_urn, urn_to_hrn, get_authority, get_leaf
 from sfa.util.sfatime import utcparse, datetime_to_string
 from sfa.util.sfalogging import logger
 
@@ -17,7 +17,7 @@ from sfa.rspecs.elements.lease import Lease
 from sfa.rspecs.elements.granularity import Granularity
 from sfa.rspecs.version_manager import VersionManager
 
-from sfa.planetlab.plxrn import PlXrn, hostname_to_urn, hrn_to_pl_slicename, slicename_to_hrn
+from sfa.planetlab.plxrn import PlXrn, hostname_to_urn, hrn_to_pl_slicename, slicename_to_hrn, xrn_to_ext_slicename, top_auth
 from sfa.planetlab.vlink import get_tc_rate
 from sfa.planetlab.topology import Topology
 
@@ -108,9 +108,15 @@ class PlAggregate:
         slice = None
         if not slice_xrn:
             return (slice, slivers)
+
         slice_urn = hrn_to_urn(slice_xrn, 'slice')
         slice_hrn, _ = urn_to_hrn(slice_xrn)
-        slice_name = hrn_to_pl_slicename(slice_hrn)
+        top_auth_hrn = top_auth(slice_hrn)
+        if top_auth_hrn == self.driver.hrn:
+            slice_name = hrn_to_pl_slicename(slice_hrn)
+        else:
+            slice_name = xrn_to_ext_slicename(slice_hrn)
+
         slices = self.driver.shell.GetSlices(slice_name)
         if not slices:
             return (slice, slivers)
@@ -142,7 +148,7 @@ class PlAggregate:
         
         return (slice, slivers)
 
-    def get_nodes_and_links(self, slice_xrn, slice=None,slivers=[], options={}, requested_slivers={}):
+    def get_nodes_and_links(self, slice_xrn, slice=None,slivers=[], options={}):
         # if we are dealing with a slice that has no node just return 
         # and empty list    
         if slice_xrn:
@@ -200,14 +206,16 @@ class PlAggregate:
             rspec_node['component_name'] = node['hostname']
             rspec_node['component_manager_id'] = Xrn(self.driver.hrn, 'authority+cm').get_urn()
             rspec_node['authority_id'] = hrn_to_urn(PlXrn.site_hrn(self.driver.hrn, site['login_base']), 'authority+sa')
-            if requested_slivers and node['hostname'] in requested_slivers:
-                requested_sliver = requested_slivers[node['hostname']]
-                if requested_sliver.get('client_id'):
-                    rspec_node['client_id'] = requested_sliver['client_id']
             # do not include boot state (<available> element) in the manifest rspec
             if not slice:     
                 rspec_node['boot_state'] = node['boot_state']
-            rspec_node['exclusive'] = 'false'
+
+            #add the exclusive tag to distinguish between Shared and Reservable nodes
+            if node['node_type'] == 'reservable':
+                rspec_node['exclusive'] = 'true'
+            else:
+                rspec_node['exclusive'] = 'false'
+
             rspec_node['hardware_types'] = [HardwareType({'name': 'plab-pc'}),
                                             HardwareType({'name': 'pc'})]
             # only doing this because protogeni rspec needs
@@ -236,13 +244,17 @@ class PlAggregate:
                 rspec_node['interfaces'].append(interface)
                 if_count+=1
 
-            tags = [PLTag(node_tags[tag_id]) for tag_id in node['node_tag_ids']]
+            tags = [PLTag(node_tags[tag_id]) for tag_id in node['node_tag_ids']\
+                    if tag_id in node_tags]
             rspec_node['tags'] = tags
             if node['node_id'] in slivers:
                 # add sliver info
                 sliver = slivers[node['node_id']]
                 rspec_node['sliver_id'] = sliver['sliver_id']
                 rspec_node['slivers'] = [sliver]
+                for tag in sliver['tags']:
+                    if tag['tagname'] == 'client_id':
+                         rspec_node['client_id'] = tag['value']
                 
                 # slivers always provide the ssh service
                 login = Login({'authentication': 'ssh-keys', 'hostname': node['hostname'], 'port':'22', 'username': sliver['name']})
@@ -252,8 +264,11 @@ class PlAggregate:
         return (rspec_nodes, links)
              
 
-    def get_leases(self, slice=None, options={}):
+    def get_leases(self, slice_xrn=None, slice=None, options={}):
         
+        if slice_xrn and not slice:
+            return []
+
         now = int(time.time())
         filter={}
         filter.update({'clip':now})
@@ -279,10 +294,18 @@ class PlAggregate:
             site_id=lease['site_id']
             site=sites_dict[site_id]
 
-            rspec_lease['lease_id'] = lease['lease_id']
-            rspec_lease['component_id'] = hostname_to_urn(self.driver.hrn, site['login_base'], lease['hostname'])
-            slice_hrn = slicename_to_hrn(self.driver.hrn, lease['name'])
-            slice_urn = hrn_to_urn(slice_hrn, 'slice')
+            #rspec_lease['lease_id'] = lease['lease_id']
+            rspec_lease['component_id'] = hrn_to_urn(self.driver.shell.GetNodeHrn(lease['hostname']), 'node')
+            #rspec_lease['component_id'] = hostname_to_urn(self.driver.hrn, site['login_base'], lease['hostname'])
+            if slice_xrn:
+                slice_urn = slice_xrn
+                slice_hrn, _ = urn_to_hrn(slice_urn)
+                # Check slice HRN
+                if slice_hrn != self.driver.shell.GetSliceHrn(lease['slice_id']):
+                    self.driver.shell.SetSliceHrn(lease['slice_id'], slice_hrn)
+            else:
+                slice_hrn = self.driver.shell.GetSliceHrn(lease['slice_id'])
+                slice_urn = hrn_to_urn(slice_hrn, 'slice')
             rspec_lease['slice_id'] = slice_urn
             rspec_lease['start_time'] = lease['t_from']
             rspec_lease['duration'] = (lease['t_until'] - lease['t_from']) / grain
@@ -290,7 +313,7 @@ class PlAggregate:
         return rspec_leases
 
     
-    def get_rspec(self, slice_xrn=None, version = None, options={}, requested_slivers={}):
+    def get_rspec(self, slice_xrn=None, version = None, options={}):
 
         version_manager = VersionManager()
         version = version_manager.get_version(version)
@@ -305,8 +328,10 @@ class PlAggregate:
             rspec.xml.set('expires',  datetime_to_string(utcparse(slice['expires'])))
 
         if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'leases':
-            nodes, links = self.get_nodes_and_links(slice_xrn, slice, slivers, options, 
-                                                    requested_slivers=requested_slivers)
+            if slice_xrn and not slivers:
+                nodes, links = [], []
+            else:
+                nodes, links = self.get_nodes_and_links(slice_xrn, slice, slivers, options)
             rspec.version.add_nodes(nodes)
             rspec.version.add_links(links)
             # add sliver defaults
@@ -314,11 +339,11 @@ class PlAggregate:
             if default_sliver:
                 default_sliver_attribs = default_sliver.get('tags', [])
                 for attrib in default_sliver_attribs:
-                    logger.info(attrib)
-                    rspec.version.add_default_sliver_attribute(attrib['tagname'], attrib['value'])
+                    logger.info("adding default sliver attribute xrn=%s attrib=%s"%(slice_xrn,attrib))
+                    rspec.version.add_default_sliver_attribute(attrib['tagname'], attrib['value'], self.driver.hrn)
         
         if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'resources':
-           leases = self.get_leases(slice)
+           leases = self.get_leases(slice_xrn, slice)
            rspec.version.add_leases(leases)
 
         return rspec.toxml()