Changing iotlabapi to iotlabshell - propagating the changes
[sfa.git] / sfa / iotlab / iotlabaggregate.py
index 77859e5..ea1131e 100644 (file)
@@ -16,7 +16,7 @@ from sfa.rspecs.elements.granularity import Granularity
 from sfa.rspecs.version_manager import VersionManager
 
 from sfa.rspecs.elements.versions.iotlabv1Node import IotlabPosition, \
-    IotlabNode, IotlabLocation
+    IotlabNode, IotlabLocation, IotlabMobility
 
 from sfa.util.sfalogging import logger
 from sfa.util.xrn import Xrn
@@ -98,52 +98,71 @@ class IotlabAggregate:
         slice_hrn, _ = urn_to_hrn(slice_xrn)
         slice_name = slice_hrn
 
-        slices = self.driver.iotlab_api.GetSlices(slice_filter=str(slice_name),
+        # GetSlices always returns a list, even if there is only one element
+        slices = self.driver.testbed_shell.GetSlices(slice_filter=str(slice_name),
                                                   slice_filter_type='slice_hrn',
                                                   login=login)
 
         logger.debug("IotlabAggregate api \tget_slice_and_slivers \
-                      sfa_slice %s \r\n slices %s self.driver.hrn %s"
-                     % (sfa_slice, slices, self.driver.hrn))
+                      slice_hrn %s \r\n slices %s self.driver.hrn %s"
+                     % (slice_hrn, slices, self.driver.hrn))
         if slices == []:
             return (sfa_slice, slivers)
 
         # sort slivers by node id , if there is a job
         #and therefore, node allocated to this slice
-        for sfa_slice in slices:
-            try:
-                node_ids_list = sfa_slice['node_ids']
-            except KeyError:
-                logger.log_exc("IOTLABAGGREGATE \t \
-                            get_slice_and_slivers No nodes in the slice \
-                            - KeyError ")
-                continue
-
-            for node in node_ids_list:
-                sliver_xrn = Xrn(slice_urn, type='sliver', id=node)
-                sliver_xrn.set_authority(self.driver.hrn)
-                sliver = Sliver({'sliver_id': sliver_xrn.urn,
-                                'name': sfa_slice['hrn'],
-                                'type': 'iotlab-node',
-                                'tags': []})
-
-                slivers[node] = sliver
+        # for sfa_slice in slices:
+        sfa_slice = slices[0]
+        try:
+            node_ids_list = sfa_slice['node_ids']
+        except KeyError:
+            logger.log_exc("IOTLABAGGREGATE \t \
+                        get_slice_and_slivers No nodes in the slice \
+                        - KeyError ")
+            node_ids_list = []
+            # continue
+
+        for node in node_ids_list:
+            sliver_xrn = Xrn(slice_urn, type='sliver', id=node)
+            sliver_xrn.set_authority(self.driver.hrn)
+            sliver = Sliver({'sliver_id': sliver_xrn.urn,
+                            'name': sfa_slice['hrn'],
+                            'type': 'iotlab-node',
+                            'tags': []})
+
+            slivers[node] = sliver
 
         #Add default sliver attribute :
         #connection information for iotlab
-        if get_authority(sfa_slice['hrn']) == self.driver.iotlab_api.root_auth:
-            tmp = sfa_slice['hrn'].split('.')
-            ldap_username = tmp[1].split('_')[0]
+        # if get_authority(sfa_slice['hrn']) == self.driver.testbed_shell.root_auth:
+        #     tmp = sfa_slice['hrn'].split('.')
+        #     ldap_username = tmp[1].split('_')[0]
+        #     ssh_access = None
+        #     slivers['default_sliver'] = {'ssh': ssh_access,
+        #                                  'login': ldap_username}
+        # look in ldap:
+        ldap_username = self.find_ldap_username_from_slice(sfa_slice)
+
+        if ldap_username is not None:
             ssh_access = None
             slivers['default_sliver'] = {'ssh': ssh_access,
-                                         'login': ldap_username}
+                                             'login': ldap_username}
 
-        #TODO get_slice_and_slivers Find the login of the external user
 
         logger.debug("IOTLABAGGREGATE api get_slice_and_slivers  slivers %s "
                      % (slivers))
         return (slices, slivers)
 
+    def find_ldap_username_from_slice(self, sfa_slice):
+        researchers = [sfa_slice['reg_researchers'][0].__dict__]
+        # look in ldap:
+        ldap_username = None
+        ret =  self.driver.testbed_shell.GetPersons(researchers)
+        if len(ret) != 0:
+            ldap_username = ret[0]['uid']
+
+        return ldap_username
+
 
     def get_nodes(self, slices=None, slivers=[], options=None):
         """Returns the nodes in the slice using the rspec format, with all the
@@ -172,6 +191,7 @@ class IotlabAggregate:
         # are part of this slice
         # but what is the role of the slivers parameter ?
         # So i assume that slice['node_ids'] will be the same as slivers for us
+        slice_nodes_list = []
         if slices is not None:
             for one_slice in slices:
                 try:
@@ -184,9 +204,9 @@ class IotlabAggregate:
                     return []
 
         # get the granularity in second for the reservation system
-        grain = self.driver.iotlab_api.GetLeaseGranularity()
+        grain = self.driver.testbed_shell.GetLeaseGranularity()
 
-        nodes = self.driver.iotlab_api.GetNodes()
+        nodes = self.driver.testbed_shell.GetNodes()
 
         nodes_dict = {}
 
@@ -194,12 +214,11 @@ class IotlabAggregate:
         # Make a list of all the nodes in the slice before getting their
         #attributes
         rspec_nodes = []
-        slice_nodes_list = []
-        logger.debug("IOTLABAGGREGATE api get_nodes slice_nodes_list  %s "
-                     % (slices))
 
+        logger.debug("IOTLABAGGREGATE api get_nodes slices  %s "
+                     % (slices))
 
-        reserved_nodes = self.driver.iotlab_api.GetNodesCurrentlyInUse()
+        reserved_nodes = self.driver.testbed_shell.GetNodesCurrentlyInUse()
         logger.debug("IOTLABAGGREGATE api get_nodes slice_nodes_list  %s "
                      % (slice_nodes_list))
         for node in nodes:
@@ -211,16 +230,16 @@ class IotlabAggregate:
                 #site_id=node['site_id']
                 #site=sites_dict[site_id]
 
-                rspec_node['mobile'] = node['mobile']
+                rspec_node['mobile'] = node['mobile']
                 rspec_node['archi'] = node['archi']
                 rspec_node['radio'] = node['radio']
 
-                iotlab_xrn = iotlab_xrn_object(self.driver.iotlab_api.root_auth,
+                iotlab_xrn = iotlab_xrn_object(self.driver.testbed_shell.root_auth,
                                                node['hostname'])
                 rspec_node['component_id'] = iotlab_xrn.urn
                 rspec_node['component_name'] = node['hostname']
                 rspec_node['component_manager_id'] = \
-                                hrn_to_urn(self.driver.iotlab_api.root_auth,
+                                hrn_to_urn(self.driver.testbed_shell.root_auth,
                                 'authority+sa')
 
                 # Iotlab's nodes are federated : there is only one authority
@@ -232,27 +251,35 @@ class IotlabAggregate:
                 # do not include boot state (<available> element)
                 #in the manifest rspec
 
-
                 rspec_node['boot_state'] = node['boot_state']
                 if node['hostname'] in reserved_nodes:
                     rspec_node['boot_state'] = "Reserved"
                 rspec_node['exclusive'] = 'true'
-                rspec_node['hardware_types'] = [HardwareType({'name': \
-                                                'iotlab-node'})]
+                rspec_node['hardware_types'] = [HardwareType({'name':
+                                               'iotlab-node'})]
 
 
-                location = IotlabLocation({'country':'France', 'site': \
+                location = IotlabLocation({'country':'France', 'site':
                                             node['site']})
                 rspec_node['location'] = location
 
+                # Adding mobility of the node in the rspec
+                mobility = IotlabMobility()
+                for field in mobility:
+                    try:
+                        mobility[field] = node[field]
+                    except KeyError, error:
+                        logger.log_exc("IOTLABAGGREGATE\t get_nodes \
+                                         mobility %s " % (error))
+                rspec_node['mobility'] = mobility
 
                 position = IotlabPosition()
-                for field in position :
+                for field in position:
                     try:
                         position[field] = node[field]
-                    except KeyError, error :
+                    except KeyError, error:
                         logger.log_exc("IOTLABAGGREGATE\t get_nodes \
-                                                        position %s "% (error))
+                                                        position %s " % (error))
 
                 rspec_node['position'] = position
                 #rspec_node['interfaces'] = []
@@ -269,22 +296,25 @@ class IotlabAggregate:
                     rspec_node['slivers'] = [sliver]
 
                     # slivers always provide the ssh service
-                    login = Login({'authentication': 'ssh-keys', \
-                            'hostname': node['hostname'], 'port':'22', \
-                            'username': sliver['name']})
+                    login = Login({'authentication': 'ssh-keys',
+                                   'hostname': node['hostname'], 'port': '22',
+                                   'username': sliver['name']})
                     service = Services({'login': login})
                     rspec_node['services'] = [service]
                 rspec_nodes.append(rspec_node)
 
         return (rspec_nodes)
 
-    def get_all_leases(self):
+    def get_all_leases(self, ldap_username):
         """
 
         Get list of lease dictionaries which all have the mandatory keys
         ('lease_id', 'hostname', 'site_id', 'name', 'start_time', 'duration').
         All the leases running or scheduled are returned.
 
+        :param ldap_username: if ldap uid is not None, looks for the leases
+        belonging to this user.
+        :type ldap_username: string
         :returns: rspec lease dictionary with keys lease_id, component_id,
             slice_id, start_time, duration.
         :rtype: dict
@@ -302,9 +332,12 @@ class IotlabAggregate:
         #if slice_record:
             #lease_filter.update({'name': slice_record['name']})
 
-        #leases = self.driver.iotlab_api.GetLeases(lease_filter)
-        leases = self.driver.iotlab_api.GetLeases()
-        grain = self.driver.iotlab_api.GetLeaseGranularity()
+        #leases = self.driver.testbed_shell.GetLeases(lease_filter)
+
+        logger.debug("IOTLABAGGREGATE  get_all_leases ldap_username %s "
+                     % (ldap_username))
+        leases = self.driver.testbed_shell.GetLeases(login=ldap_username)
+        grain = self.driver.testbed_shell.GetLeaseGranularity()
         # site_ids = []
         rspec_leases = []
         for lease in leases:
@@ -313,7 +346,7 @@ class IotlabAggregate:
                 rspec_lease = Lease()
                 rspec_lease['lease_id'] = lease['lease_id']
                 #site = node['site_id']
-                iotlab_xrn = iotlab_xrn_object(self.driver.iotlab_api.root_auth,
+                iotlab_xrn = iotlab_xrn_object(self.driver.testbed_shell.root_auth,
                                                node)
                 rspec_lease['component_id'] = iotlab_xrn.urn
                 #rspec_lease['component_id'] = hostname_to_urn(self.driver.hrn,\
@@ -321,33 +354,32 @@ class IotlabAggregate:
                 try:
                     rspec_lease['slice_id'] = lease['slice_id']
                 except KeyError:
-                    #No info on the slice used in iotlab_xp table
+                    #No info on the slice used in testbed_xp table
                     pass
                 rspec_lease['start_time'] = lease['t_from']
                 rspec_lease['duration'] = (lease['t_until'] - lease['t_from']) \
-                    / grain
+                     / grain
                 rspec_leases.append(rspec_lease)
         return rspec_leases
 
     def get_rspec(self, slice_xrn=None, login=None, version=None,
                   options=None):
         """
-
         Returns xml rspec:
-            - a full advertisement rspec with the testbed resources if slice_xrn
-             is not specified.If a lease option is given, also returns the
-             leases scheduled on the testbed.
-            - a manifest Rspec with the leases and nodes in slice's leases
-            if slice_xrn is not None.
+        - a full advertisement rspec with the testbed resources if slice_xrn is
+        not specified.If a lease option is given, also returns the leases
+        scheduled on the testbed.
+        - a manifest Rspec with the leases and nodes in slice's leases if
+        slice_xrn is not None.
 
         :param slice_xrn: srn of the slice
+        :type slice_xrn: string
         :param login: user'uid (ldap login) on iotlab
+        :type login: string
         :param version: can be set to sfa or iotlab
+        :type version: RSpecVersion
         :param options: used to specify if the leases should also be included in
             the returned rspec.
-        :type slice_xrn: string
-        :type login: string
-        :type version: RSpecVersion
         :type options: dict
 
         :returns: Xml Rspec.
@@ -356,6 +388,7 @@ class IotlabAggregate:
 
         """
 
+        ldap_username = None
         rspec = None
         version_manager = VersionManager()
         version = version_manager.get_version(version)
@@ -372,6 +405,17 @@ class IotlabAggregate:
                 version.type, version.version, 'manifest')
 
         slices, slivers = self.get_slice_and_slivers(slice_xrn, login)
+        if slice_xrn and slices is not None:
+            #Get user associated with this slice
+            #for one_slice in slices :
+            ldap_username = self.find_ldap_username_from_slice(slices[0])
+            # ldap_username = slices[0]['reg_researchers'][0].__dict__['hrn']
+            #  # ldap_username = slices[0]['user']
+            # tmp = ldap_username.split('.')
+            # ldap_username = tmp[1]
+            logger.debug("IotlabAggregate \tget_rspec **** \
+                    LDAP USERNAME %s \r\n" \
+                    % (ldap_username))
         #at this point sliver may be empty if no iotlab job
         #is running for this user/slice.
         rspec = RSpec(version=rspec_version, user_options=options)
@@ -380,7 +424,7 @@ class IotlabAggregate:
                       slice_xrn %s slices  %s\r\n \r\n"
                      % (slice_xrn, slices))
 
-        if options is not None:
+        if options is not None and 'list_leases' in options:
             lease_option = options['list_leases']
         else:
             #If no options are specified, at least print the resources
@@ -392,27 +436,35 @@ class IotlabAggregate:
         #if not options.get('list_leases') or options.get('list_leases')
         #and options['list_leases'] != 'leases':
             nodes = self.get_nodes(slices, slivers)
-            logger.debug("\r\n \r\n IotlabAggregate \t lease_option %s \
+            if slice_xrn and slices is None:
+              nodes = []
+            logger.debug("\r\n")
+            logger.debug("IotlabAggregate \t lease_option %s \
                           get rspec  ******* nodes %s"
-                         % (lease_option, nodes[0]))
+                         % (lease_option, nodes))
 
             sites_set = set([node['location']['site'] for node in nodes])
 
             #In case creating a job,  slice_xrn is not set to None
             rspec.version.add_nodes(nodes)
-            if slice_xrn:
-                #Get user associated with this slice
-                #for one_slice in slices :
-                ldap_username = slices[0]['hrn']
-                tmp = ldap_username.split('.')
-                ldap_username = tmp[1].split('_')[0]
+            if slice_xrn and slices is not None:
+            #     #Get user associated with this slice
+            #     #for one_slice in slices :
+            #     ldap_username = slices[0]['reg_researchers']
+            #      # ldap_username = slices[0]['user']
+            #     tmp = ldap_username.split('.')
+            #     ldap_username = tmp[1]
+            #      # ldap_username = tmp[1].split('_')[0]
 
+                logger.debug("IotlabAggregate \tget_rspec **** \
+                        version type %s ldap_ user %s \r\n" \
+                        % (version.type, ldap_username))
                 if version.type == "Iotlab":
                     rspec.version.add_connection_information(
                         ldap_username, sites_set)
 
             default_sliver = slivers.get('default_sliver', [])
-            if default_sliver:
+            if default_sliver and len(nodes) is not 0:
                 #default_sliver_attribs = default_sliver.get('tags', [])
                 logger.debug("IotlabAggregate \tget_rspec **** \
                         default_sliver%s \r\n" % (default_sliver))
@@ -421,6 +473,8 @@ class IotlabAggregate:
                         attrib, default_sliver[attrib])
 
         if lease_option in ['all','leases']:
-            leases = self.get_all_leases()
+            leases = self.get_all_leases(ldap_username)
             rspec.version.add_leases(leases)
+            logger.debug("IotlabAggregate \tget_rspec **** \
+                       FINAL RSPEC %s \r\n" % (rspec.toxml()))
         return rspec.toxml()