Porting cortexlab to geni-v3.
authorSandrine Avakian <sandrine.avakian@inria.fr>
Thu, 9 Jan 2014 16:20:06 +0000 (17:20 +0100)
committerSandrine Avakian <sandrine.avakian@inria.fr>
Thu, 9 Jan 2014 16:20:06 +0000 (17:20 +0100)
May try to factor the code in the future, as Iotlab and Cortexlab drivers are similar.

sfa/cortexlab/cortexlabaggregate.py
sfa/cortexlab/cortexlabdriver.py
sfa/cortexlab/cortexlabshell.py

index f58acc6..d9cddf3 100644 (file)
@@ -3,55 +3,31 @@ File providing methods to generate valid RSpecs for the Iotlab testbed.
 Contains methods to get information on slice, slivers, nodes and leases,
 formatting them and turn it into a RSpec.
 """
 Contains methods to get information on slice, slivers, nodes and leases,
 formatting them and turn it into a RSpec.
 """
-from sfa.util.xrn import hrn_to_urn, urn_to_hrn, get_authority
+from sfa.util.xrn import hrn_to_urn, urn_to_hrn
+from sfa.util.sfatime import utcparse, datetime_to_string
 
 
+from sfa.iotlab.iotlabxrn import IotlabXrn, xrn_object
 from sfa.rspecs.rspec import RSpec
 from sfa.rspecs.rspec import RSpec
+
 #from sfa.rspecs.elements.location import Location
 from sfa.rspecs.elements.hardware_type import HardwareType
 #from sfa.rspecs.elements.location import Location
 from sfa.rspecs.elements.hardware_type import HardwareType
+from sfa.rspecs.elements.node import NodeElement
 from sfa.rspecs.elements.login import Login
 from sfa.rspecs.elements.login import Login
-from sfa.rspecs.elements.services import Services
 from sfa.rspecs.elements.sliver import Sliver
 from sfa.rspecs.elements.lease import Lease
 from sfa.rspecs.elements.granularity import Granularity
 from sfa.rspecs.version_manager import VersionManager
 from sfa.rspecs.elements.sliver import Sliver
 from sfa.rspecs.elements.lease import Lease
 from sfa.rspecs.elements.granularity import Granularity
 from sfa.rspecs.version_manager import VersionManager
-
+from sfa.storage.model import SliverAllocation
 from sfa.rspecs.elements.versions.iotlabv1Node import IotlabPosition, \
 from sfa.rspecs.elements.versions.iotlabv1Node import IotlabPosition, \
-    IotlabNode, IotlabLocation, IotlabMobility
+    IotlabLocation
 
 from sfa.util.sfalogging import logger
 from sfa.util.xrn import Xrn
 
 
 from sfa.util.sfalogging import logger
 from sfa.util.xrn import Xrn
 
-
-def cortexlab_xrn_to_hostname(xrn):
-    """Returns a node's hostname from its xrn.
-    :param xrn: The nodes xrn identifier.
-    :type xrn: Xrn (from sfa.util.xrn)
-
-    :returns: node's hostname.
-    :rtype: string
-
-    """
-    return Xrn.unescape(Xrn(xrn=xrn, type='node').get_leaf())
-
-
-def cortexlab_xrn_object(root_auth, hostname):
-    """Creates a valid xrn object from the node's hostname and the authority
-    of the SFA server.
-
-    :param hostname: the node's hostname.
-    :param root_auth: the SFA root authority.
-    :type hostname: string
-    :type root_auth: string
-
-    :returns: the cortexlab node's xrn
-    :rtype: Xrn
-
-    """
-    return Xrn('.'.join([root_auth, Xrn.escape(hostname)]), type='node')
-
+import time
 
 class CortexlabAggregate:
 
 class CortexlabAggregate:
-    """Aggregate manager class for Iotlab. """
+    """Aggregate manager class for cortexlab. """
 
     sites = {}
     nodes = {}
 
     sites = {}
     nodes = {}
@@ -98,14 +74,13 @@ class CortexlabAggregate:
             return (sfa_slice, slivers)
         slice_urn = hrn_to_urn(slice_xrn, 'slice')
         slice_hrn, _ = urn_to_hrn(slice_xrn)
             return (sfa_slice, slivers)
         slice_urn = hrn_to_urn(slice_xrn, 'slice')
         slice_hrn, _ = urn_to_hrn(slice_xrn)
-        slice_name = slice_hrn
 
         # GetSlices always returns a list, even if there is only one element
 
         # GetSlices always returns a list, even if there is only one element
-        slices = self.driver.testbed_shell.GetSlices(slice_filter=str(slice_name),
+        slices = self.driver.GetSlices(slice_filter=str(slice_hrn),
                                                   slice_filter_type='slice_hrn',
                                                   login=login)
 
                                                   slice_filter_type='slice_hrn',
                                                   login=login)
 
-        logger.debug("IotlabAggregate api \tget_slice_and_slivers \
+        logger.debug("CortexlabAggregate api \tget_slice_and_slivers \
                       slice_hrn %s \r\n slices %s self.driver.hrn %s"
                      % (slice_hrn, slices, self.driver.hrn))
         if slices == []:
                       slice_hrn %s \r\n slices %s self.driver.hrn %s"
                      % (slice_hrn, slices, self.driver.hrn))
         if slices == []:
@@ -152,6 +127,17 @@ class CortexlabAggregate:
 
 
     def find_ldap_username_from_slice(self, sfa_slice):
 
 
     def find_ldap_username_from_slice(self, sfa_slice):
+        """
+        Gets the ldap username of the user based on the information contained
+        in ist sfa_slice record.
+
+        :param sfa_slice: the user's slice record. Must contain the
+            reg_researchers key.
+        :type sfa_slice: dictionary
+        :returns: ldap_username, the ldap user's login.
+        :rtype: string
+        """
+
         researchers = [sfa_slice['reg_researchers'][0].__dict__]
         # look in ldap:
         ldap_username = None
         researchers = [sfa_slice['reg_researchers'][0].__dict__]
         # look in ldap:
         ldap_username = None
@@ -163,7 +149,7 @@ class CortexlabAggregate:
 
 
 
 
 
 
-    def get_nodes(self, slices=None, slivers=[], options=None):
+    def get_nodes(self, options=None):
         """Returns the nodes in the slice using the rspec format, with all the
         nodes' properties.
 
         """Returns the nodes in the slice using the rspec format, with all the
         nodes' properties.
 
@@ -172,10 +158,6 @@ class CortexlabAggregate:
         it. If the slice does not have any job running or scheduled, that is
         it has no reserved nodes, then returns an empty list.
 
         it. If the slice does not have any job running or scheduled, that is
         it has no reserved nodes, then returns an empty list.
 
-        :param slices: list of slices (record dictionaries)
-        :param slivers: the list of slivers in all the slices
-        :type slices: list of dicts
-        :type slivers: list of Sliver object (dictionaries)
         :returns: An empty list if the slice has no reserved nodes, a rspec
             list with all the nodes and their properties (a dict per node)
             otherwise.
         :returns: An empty list if the slice has no reserved nodes, a rspec
             list with all the nodes and their properties (a dict per node)
             otherwise.
@@ -184,98 +166,224 @@ class CortexlabAggregate:
         .. seealso:: get_slice_and_slivers
 
         """
         .. seealso:: get_slice_and_slivers
 
         """
-        # NT: the semantic of this function is not clear to me :
-        # if slice is not defined, then all the nodes should be returned
-        # if slice is defined, we should return only the nodes that
-        # 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:
-                    slice_nodes_list = one_slice['node_ids']
-                     # if we are dealing with a slice that has no node just
-                     # return an empty list. In cortexlab a slice can have multiple
-                     # jobs scheduled, so it either has at least one lease or
-                     # not at all.
-                except KeyError:
-                    return []
+        filter_nodes = None
+        if options:
+            geni_available = options.get('geni_available')
+            if geni_available == True:
+                filter_nodes['boot_state'] = ['Alive']
+
+        slice_nodes_list = []
+        if slices is not None:
+            for one_slice in slices:
+                try:
+                    slice_nodes_list = one_slice['node_ids']
+    #              # if we are dealing with a slice that has no node just
+    #              # return an empty list. In iotlab a slice can have multiple
+    #              # jobs scheduled, so it either has at least one lease or
+    #              # not at all.
+                except KeyError:
+                    return []
 
         # get the granularity in second for the reservation system
 
         # get the granularity in second for the reservation system
-        grain = self.driver.testbed_shell.GetLeaseGranularity()
+        grain = self.driver.testbed_shell.GetLeaseGranularity()
 
 
-        nodes = self.driver.testbed_shell.GetNodes()
+        nodes = self.driver.testbed_shell.GetNodes(node_filter_dict =
+                                                    filter_nodes)
 
         nodes_dict = {}
 
         #if slices, this means we got to list all the nodes given to this slice
         # Make a list of all the nodes in the slice before getting their
         #attributes
 
         nodes_dict = {}
 
         #if slices, this means we got to list all the nodes given to this slice
         # Make a list of all the nodes in the slice before getting their
         #attributes
-        rspec_nodes = []
 
 
-        logger.debug("CortexlabAggregate api get_nodes slices  %s "
-                     % (slices))
-
-        reserved_nodes = self.driver.testbed_shell.GetNodesCurrentlyInUse()
-        logger.debug("CortexlabAggregate api get_nodes slice_nodes_list  %s "
-                     % (slice_nodes_list))
         for node in nodes:
             nodes_dict[node['node_id']] = node
         for node in nodes:
             nodes_dict[node['node_id']] = node
-            if slice_nodes_list == [] or node['hostname'] in slice_nodes_list:
 
 
-                rspec_node = Node()
+        return nodes_dict
+
+
+    def node_to_rspec_node(self, node):
+        """ Creates a rspec node structure with the appropriate information
+        based on the node information that can be found in the node dictionary.
 
 
+        :param node: node data. this dict contains information about the node
+            and must have the following keys : mobile, radio, archi, hostname,
+            boot_state, site, x, y ,z (position).
+        :type node: dictionary.
 
 
+        :returns: node dictionary containing the following keys : mobile, archi,
+            radio, component_id, component_name, component_manager_id,
+            authority_id, boot_state, exclusive, hardware_types, location,
+            position, granularity, tags.
+        :rtype: dict
+
+        """
 
 
-                cortexlab_xrn = cortexlab_xrn_object(self.driver.testbed_shell.root_auth,
+        grain = self.driver.testbed_shell.GetLeaseGranularity()
+        rspec_node = NodeElement()
+
+        # xxx how to retrieve site['login_base']
+        #site_id=node['site_id']
+        #site=sites_dict[site_id]
+
+        rspec_node['mobile'] = node['mobile']
+        rspec_node['archi'] = node['archi']
+        rspec_node['radio'] = node['radio']
+        cortexlab_xrn = xrn_object(self.driver.testbed_shell.root_auth,
                                                node['hostname'])
                                                node['hostname'])
-                rspec_node['component_id'] = cortexlab_xrn.urn
-                rspec_node['component_name'] = node['hostname']
-                rspec_node['component_manager_id'] = \
-                                hrn_to_urn(self.driver.testbed_shell.root_auth,
-                                'authority+sa')
-
-                # Iotlab's nodes are federated : there is only one authority
-                # for all Iotlab sites, registered in SFA.
-                # Removing the part including the site
-                # in authority_id SA 27/07/12
-                rspec_node['authority_id'] = rspec_node['component_manager_id']
-
-
-                # boot state removed if you need it uncomment
-                # 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':
-                                               'cortexlab-node'})]
-
-
-                # Location, mobility and position removed. If you need it go check
-                # get_nodes in iotlabaggregate.py
-
-                # Granularity
-                granularity = Granularity({'grain': grain})
-                rspec_node['granularity'] = granularity
-                rspec_node['tags'] = []
-                if node['hostname'] in slivers:
-                    # add sliver info
-                    sliver = slivers[node['hostname']]
-                    rspec_node['sliver_id'] = sliver['sliver_id']
-                    rspec_node['client_id'] = node['hostname']
-                    rspec_node['slivers'] = [sliver]
-
-                    # slivers always provide the ssh service
-                    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)
+        rspec_node['component_id'] = cortexlab_xrn.urn
+        rspec_node['component_name'] = node['hostname']
+        rspec_node['component_manager_id'] = \
+                        hrn_to_urn(self.driver.testbed_shell.root_auth,
+                        'authority+sa')
+
+        # Iotlab's nodes are federated : there is only one authority
+        # for all Iotlab sites, registered in SFA.
+        # Removing the part including the site
+        # in authority_id SA 27/07/12
+        rspec_node['authority_id'] = rspec_node['component_manager_id']
+
+        # 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'})]
+
+        location = IotlabLocation({'country':'France', 'site': \
+                                    node['site']})
+        rspec_node['location'] = location
+
+
+        position = IotlabPosition()
+        for field in position :
+            try:
+                position[field] = node[field]
+            except KeyError, error :
+                logger.log_exc("Cortexlabaggregate\t node_to_rspec_node \
+                                                position %s "% (error))
+
+        rspec_node['position'] = position
+
+
+        # Granularity
+        granularity = Granularity({'grain': grain})
+        rspec_node['granularity'] = granularity
+        rspec_node['tags'] = []
+        # if node['hostname'] in slivers:
+        #     # add sliver info
+        #     sliver = slivers[node['hostname']]
+        #     rspec_node['sliver_id'] = sliver['sliver_id']
+        #     rspec_node['client_id'] = node['hostname']
+        #     rspec_node['slivers'] = [sliver]
+
+        #     # slivers always provide the ssh service
+        #     login = Login({'authentication': 'ssh-keys', \
+        #             'hostname': node['hostname'], 'port':'22', \
+        #             'username': sliver['name']})
+        #     service = Services({'login': login})
+        #     rspec_node['services'] = [service]
+
+        return rspec_node
+
+
+    def rspec_node_to_geni_sliver(self, rspec_node, sliver_allocations = {}):
+        """Makes a geni sliver structure from all the nodes allocated
+        to slivers in the sliver_allocations dictionary. Returns the states
+        of the sliver.
+
+        :param rspec_node: Node information contained in a rspec data structure
+            fashion.
+        :type rspec_node: dictionary
+        :param sliver_allocations:
+        :type sliver_allocations: dictionary
+
+        :returns: Dictionary with the following keys: geni_sliver_urn,
+            geni_expires, geni_allocation_status, geni_operational_status,
+            geni_error.
+
+        :rtype: dictionary
+
+        .. seealso:: node_to_rspec_node
+
+        """
+        if rspec_node['sliver_id'] in sliver_allocations:
+            # set sliver allocation and operational status
+            sliver_allocation = sliver_allocations[rspec_node['sliver_id']]
+            if sliver_allocation:
+                allocation_status = sliver_allocation.allocation_state
+                if allocation_status == 'geni_allocated':
+                    op_status =  'geni_pending_allocation'
+                elif allocation_status == 'geni_provisioned':
+                    op_status = 'geni_ready'
+                else:
+                    op_status = 'geni_unknown'
+            else:
+                allocation_status = 'geni_unallocated'
+        else:
+            allocation_status = 'geni_unallocated'
+            op_status = 'geni_failed'
+        # required fields
+        geni_sliver = {'geni_sliver_urn': rspec_node['sliver_id'],
+                       'geni_expires': rspec_node['expires'],
+                       'geni_allocation_status' : allocation_status,
+                       'geni_operational_status': op_status,
+                       'geni_error': '',
+                       }
+        return geni_sliver
+
+    def sliver_to_rspec_node(self, sliver, sliver_allocations):
+        """Used by describe to format node information into a rspec compliant
+        structure.
+
+        Creates a node rspec compliant structure by calling node_to_rspec_node.
+        Adds slivers, if any, to rspec node structure. Returns the updated
+        rspec node struct.
+
+        :param sliver: sliver dictionary. Contains keys: urn, slice_id, hostname
+            and slice_name.
+        :type sliver: dictionary
+        :param sliver_allocations: dictionary of slivers
+        :type sliver_allocations: dict
+
+        :returns: Node dictionary with all necessary data.
+
+        .. seealso:: node_to_rspec_node
+        """
+        rspec_node = self.node_to_rspec_node(sliver)
+        rspec_node['expires'] = datetime_to_string(utcparse(sliver['expires']))
+        # add sliver info
+        logger.debug("CORTEXLABAGGREGATE api \t  sliver_to_rspec_node sliver \
+                        %s \r\nsliver_allocations %s" % (sliver,
+                            sliver_allocations))
+        rspec_sliver = Sliver({'sliver_id': sliver['urn'],
+                         'name': sliver['slice_id'],
+                         'type': 'iotlab-exclusive',
+                         'tags': []})
+        rspec_node['sliver_id'] = rspec_sliver['sliver_id']
+
+        if sliver['urn'] in sliver_allocations:
+            rspec_node['client_id'] = sliver_allocations[
+                                                    sliver['urn']].client_id
+            if sliver_allocations[sliver['urn']].component_id:
+                rspec_node['component_id'] = sliver_allocations[
+                                                    sliver['urn']].component_id
+        rspec_node['slivers'] = [rspec_sliver]
+
+        # slivers always provide the ssh service
+        login = Login({'authentication': 'ssh-keys',
+                       'hostname': sliver['hostname'],
+                       'port':'22',
+                       'username': sliver['slice_name'],
+                       'login': sliver['slice_name']
+                      })
+        return rspec_node
+
 
     def get_all_leases(self, ldap_username):
         """
 
     def get_all_leases(self, ldap_username):
         """
@@ -285,10 +393,13 @@ class CortexlabAggregate:
         All the leases running or scheduled are returned.
 
         :param ldap_username: if ldap uid is not None, looks for the leases
         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.
+            belonging to this user.
         :type ldap_username: string
         :returns: rspec lease dictionary with keys lease_id, component_id,
         :type ldap_username: string
         :returns: rspec lease dictionary with keys lease_id, component_id,
-            slice_id, start_time, duration.
+            slice_id, start_time, duration where the lease_id is the oar job id,
+            component_id is the node's urn, slice_id is the slice urn,
+            start_time is the timestamp starting time and duration is expressed
+            in terms of the testbed's granularity.
         :rtype: dict
 
         .. note::There is no filtering of leases within a given time frame.
         :rtype: dict
 
         .. note::There is no filtering of leases within a given time frame.
@@ -298,14 +409,9 @@ class CortexlabAggregate:
 
         """
 
 
         """
 
-        #now = int(time.time())
-        #lease_filter = {'clip': now }
-
-
-
         logger.debug("CortexlabAggregate  get_all_leases ldap_username %s "
                      % (ldap_username))
         logger.debug("CortexlabAggregate  get_all_leases ldap_username %s "
                      % (ldap_username))
-        leases = self.driver.testbed_shell.GetLeases(login=ldap_username)
+        leases = self.driver.driver.GetLeases(login=ldap_username)
         grain = self.driver.testbed_shell.GetLeaseGranularity()
         # site_ids = []
         rspec_leases = []
         grain = self.driver.testbed_shell.GetLeaseGranularity()
         # site_ids = []
         rspec_leases = []
@@ -315,7 +421,7 @@ class CortexlabAggregate:
                 rspec_lease = Lease()
                 rspec_lease['lease_id'] = lease['lease_id']
 
                 rspec_lease = Lease()
                 rspec_lease['lease_id'] = lease['lease_id']
 
-                cortexlab_xrn = cortexlab_xrn_object(
+                cortexlab_xrn = xrn_object(
                     self.driver.testbed_shell.root_auth, node)
                 rspec_lease['component_id'] = cortexlab_xrn.urn
                 #rspec_lease['component_id'] = hostname_to_urn(self.driver.hrn,\
                     self.driver.testbed_shell.root_auth, node)
                 rspec_lease['component_id'] = cortexlab_xrn.urn
                 #rspec_lease['component_id'] = hostname_to_urn(self.driver.hrn,\
@@ -393,7 +499,7 @@ class CortexlabAggregate:
                       slice_xrn %s slices  %s\r\n \r\n"
                      % (slice_xrn, slices))
 
                       slice_xrn %s slices  %s\r\n \r\n"
                      % (slice_xrn, slices))
 
-        if options is not None and 'list_leases' in options:
+        if options is not None :
             lease_option = options['list_leases']
         else:
             #If no options are specified, at least print the resources
             lease_option = options['list_leases']
         else:
             #If no options are specified, at least print the resources
@@ -404,9 +510,7 @@ class CortexlabAggregate:
         if lease_option in ['all', 'resources']:
         #if not options.get('list_leases') or options.get('list_leases')
         #and options['list_leases'] != 'leases':
         if lease_option in ['all', 'resources']:
         #if not options.get('list_leases') or options.get('list_leases')
         #and options['list_leases'] != 'leases':
-            nodes = self.get_nodes(slices, slivers)
-            if slice_xrn and slices is None:
-              nodes = []
+            nodes = self.get_nodes()
             logger.debug("\r\n")
             logger.debug("CortexlabAggregate \t lease_option %s \
                           get rspec  ******* nodes %s"
             logger.debug("\r\n")
             logger.debug("CortexlabAggregate \t lease_option %s \
                           get rspec  ******* nodes %s"
@@ -428,7 +532,8 @@ class CortexlabAggregate:
                 logger.debug("CortexlabAggregate \tget_rspec **** \
                         version type %s ldap_ user %s \r\n" \
                         % (version.type, ldap_username))
                 logger.debug("CortexlabAggregate \tget_rspec **** \
                         version type %s ldap_ user %s \r\n" \
                         % (version.type, ldap_username))
-                if version.type == "Iotlab":
+                #TODO : Change the version of Rspec here in case of pbm -SA 09/01/14
+                if version.type in ["Cortexlab", "Iotlab"]:
                     rspec.version.add_connection_information(
                         ldap_username, sites_set)
 
                     rspec.version.add_connection_information(
                         ldap_username, sites_set)
 
@@ -447,3 +552,257 @@ class CortexlabAggregate:
             logger.debug("CortexlabAggregate \tget_rspec **** \
                        FINAL RSPEC %s \r\n" % (rspec.toxml()))
         return rspec.toxml()
             logger.debug("CortexlabAggregate \tget_rspec **** \
                        FINAL RSPEC %s \r\n" % (rspec.toxml()))
         return rspec.toxml()
+
+
+
+    def get_slivers(self, urns, options={}):
+        """Get slivers of the given slice urns. Slivers contains slice, node and
+        user information.
+
+        For Iotlab, returns the leases with sliver ids and their allocation
+        status.
+
+        :param urns: list of  slice urns.
+        :type urns: list of strings
+        :param options: unused
+        :type options: unused
+
+        .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns
+        """
+
+
+        slice_ids = set()
+        node_ids = []
+        for urn in urns:
+            xrn = IotlabXrn(xrn=urn)
+            if xrn.type == 'sliver':
+                 # id: slice_id-node_id
+                try:
+                    sliver_id_parts = xrn.get_sliver_id_parts()
+                    slice_id = int(sliver_id_parts[0])
+                    node_id = int(sliver_id_parts[1])
+                    slice_ids.add(slice_id)
+                    node_ids.append(node_id)
+                except ValueError:
+                    pass
+            else:
+                slice_names = set()
+                slice_names.add(xrn.hrn)
+
+
+        logger.debug("CortexlabAggregate \t get_slivers urns %s slice_ids %s \
+                       node_ids %s\r\n" % (urns, slice_ids, node_ids))
+        logger.debug("CortexlabAggregate \t get_slivers xrn %s slice_names %s \
+                       \r\n" % (xrn, slice_names))
+        filter_sliver = {}
+        if slice_names:
+            filter_sliver['slice_hrn'] = list(slice_names)
+            slice_hrn = filter_sliver['slice_hrn'][0]
+
+            slice_filter_type = 'slice_hrn'
+
+        # if slice_ids:
+        #     filter['slice_id'] = list(slice_ids)
+        # # get slices
+        if slice_hrn:
+            slices = self.driver.GetSlices(slice_hrn,
+                slice_filter_type)
+            leases = self.driver.GetLeases({'slice_hrn':slice_hrn})
+        logger.debug("CortexlabAggregate \t get_slivers \
+                       slices %s leases %s\r\n" % (slices, leases ))
+        if not slices:
+            return []
+
+        single_slice = slices[0]
+        # get sliver users
+        user = single_slice['reg_researchers'][0].__dict__
+        logger.debug("CortexlabAggregate \t get_slivers user %s \
+                       \r\n" % (user))
+
+        # construct user key info
+        person = self.driver.testbed_shell.ldap.LdapFindUser(record=user)
+        logger.debug("CortexlabAggregate \t get_slivers person %s \
+                       \r\n" % (person))
+        # name = person['last_name']
+        user['login'] = person['uid']
+        user['user_urn'] = hrn_to_urn(user['hrn'], 'user')
+        user['keys'] = person['pkey']
+
+
+        try:
+            node_ids = single_slice['node_ids']
+            node_list = self.driver.testbed_shell.GetNodes(
+                    {'hostname':single_slice['node_ids']})
+            node_by_hostname = dict([(node['hostname'], node)
+                                        for node in node_list])
+        except KeyError:
+            logger.warning("\t get_slivers No slivers in slice")
+            # slice['node_ids'] = node_ids
+        # nodes_dict = self.get_slice_nodes(slice, options)
+
+        slivers = []
+        for current_lease in leases:
+            for hostname in current_lease['reserved_nodes']:
+                node = {}
+                node['slice_id'] = current_lease['slice_id']
+                node['slice_hrn'] = current_lease['slice_hrn']
+                slice_name = current_lease['slice_hrn'].split(".")[1]
+                node['slice_name'] = slice_name
+                index = current_lease['reserved_nodes'].index(hostname)
+                node_id = current_lease['resource_ids'][index]
+                # node['slice_name'] = user['login']
+                # node.update(single_slice)
+                more_info = node_by_hostname[hostname]
+                node.update(more_info)
+                # oar_job_id is the slice_id (lease_id)
+                sliver_hrn = '%s.%s-%s' % (self.driver.hrn,
+                            current_lease['lease_id'], node_id)
+                node['node_id'] = node_id
+                node['expires'] = current_lease['t_until']
+                node['sliver_id'] = Xrn(sliver_hrn, type='sliver').urn
+                node['urn'] = node['sliver_id']
+                node['services_user'] = [user]
+
+                slivers.append(node)
+        return slivers
+
+
+    def list_resources(self, version = None, options={}):
+        """
+        Returns an advertisement Rspec of available resources at this
+        aggregate. This Rspec contains a resource listing along with their
+        description, providing sufficient information for clients to be able to
+        select among available resources.
+
+        :param options: various options. The valid options are: {boolean
+            geni_compressed <optional>; struct geni_rspec_version { string type;
+            #case insensitive , string version; # case insensitive}} . The only
+            mandatory options if options is specified is geni_rspec_version.
+        :type options: dictionary
+
+        :returns: On success, the value field of the return struct will contain
+            a geni.rspec advertisment RSpec
+        :rtype: Rspec advertisement in xml.
+
+        .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#RSpecdatatype
+        .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3#ListResources
+        """
+
+        version_manager = VersionManager()
+        version = version_manager.get_version(version)
+        rspec_version = version_manager._get_version(version.type,
+                                                    version.version, 'ad')
+        rspec = RSpec(version=rspec_version, user_options=options)
+        # variable ldap_username to be compliant with  get_all_leases
+        # prototype. Now unused in geni-v3 since we are getting all the leases
+        # here
+        ldap_username = None
+        if not options.get('list_leases') or options['list_leases'] != 'leases':
+            # get nodes
+            nodes_dict  = self.get_nodes(options)
+
+            # no interfaces on iotlab nodes
+            # convert nodes to rspec nodes
+            rspec_nodes = []
+            for node_id in nodes_dict:
+                node = nodes_dict[node_id]
+                rspec_node = self.node_to_rspec_node(node)
+                rspec_nodes.append(rspec_node)
+            rspec.version.add_nodes(rspec_nodes)
+
+            # add links
+            # links = self.get_links(sites, nodes_dict, interfaces)
+            # rspec.version.add_links(links)
+
+        if not options.get('list_leases') or options.get('list_leases') \
+            and options['list_leases'] != 'resources':
+            leases = self.get_all_leases(ldap_username)
+            rspec.version.add_leases(leases)
+
+        return rspec.toxml()
+
+
+    def describe(self, urns, version=None, options={}):
+        """
+        Retrieve a manifest RSpec describing the resources contained by the
+        named entities, e.g. a single slice or a set of the slivers in a slice.
+        This listing and description should be sufficiently descriptive to allow
+        experimenters to use the resources.
+
+        :param urns: If a slice urn is supplied and there are no slivers in the
+            given slice at this aggregate, then geni_rspec shall be a valid
+            manifest RSpec, containing no node elements - no resources.
+        :type urns: list  or strings
+        :param options: various options. the valid options are: {boolean
+            geni_compressed <optional>; struct geni_rspec_version { string type;
+            #case insensitive , string version; # case insensitive}}
+        :type options: dictionary
+
+        :returns: On success returns the following dictionary {geni_rspec:
+            <geni.rspec, a Manifest RSpec>, geni_urn: <string slice urn of the
+            containing slice>, geni_slivers:{ geni_sliver_urn:
+            <string sliver urn>, geni_expires:  <dateTime.rfc3339 allocation
+            expiration string, as in geni_expires from SliversStatus>,
+            geni_allocation_status: <string sliver state - e.g. geni_allocated
+            or geni_provisioned >, geni_operational_status:
+            <string sliver operational state>, geni_error: <optional string.
+            The field may be omitted entirely but may not be null/None,
+            explaining any failure for a sliver.>}
+
+        .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3#Describe
+        .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns
+        """
+        version_manager = VersionManager()
+        version = version_manager.get_version(version)
+        rspec_version = version_manager._get_version(
+                                    version.type, version.version, 'manifest')
+        rspec = RSpec(version=rspec_version, user_options=options)
+
+        # get slivers
+        geni_slivers = []
+        slivers = self.get_slivers(urns, options)
+        if slivers:
+            rspec_expires = datetime_to_string(utcparse(slivers[0]['expires']))
+        else:
+            rspec_expires = datetime_to_string(utcparse(time.time()))
+        rspec.xml.set('expires',  rspec_expires)
+
+        # lookup the sliver allocations
+        geni_urn = urns[0]
+        sliver_ids = [sliver['sliver_id'] for sliver in slivers]
+        logger.debug(" Cortexlabaggregate.PY \tDescribe  sliver_ids %s "
+                     % (sliver_ids))
+        constraint = SliverAllocation.sliver_id.in_(sliver_ids)
+        query = self.driver.api.dbsession().query(SliverAllocation)
+        sliver_allocations = query.filter((constraint)).all()
+        logger.debug(" Cortexlabaggregate.PY \tDescribe  sliver_allocations %s "
+                     % (sliver_allocations))
+        sliver_allocation_dict = {}
+        for sliver_allocation in sliver_allocations:
+            geni_urn = sliver_allocation.slice_urn
+            sliver_allocation_dict[sliver_allocation.sliver_id] = \
+                                                            sliver_allocation
+
+        # add slivers
+        nodes_dict = {}
+        for sliver in slivers:
+            nodes_dict[sliver['node_id']] = sliver
+        rspec_nodes = []
+        for sliver in slivers:
+            rspec_node = self.sliver_to_rspec_node(sliver,
+                                                    sliver_allocation_dict)
+            rspec_nodes.append(rspec_node)
+            logger.debug(" Cortexlabaggregate.PY \tDescribe  sliver_allocation_dict %s "
+                     % (sliver_allocation_dict))
+            geni_sliver = self.rspec_node_to_geni_sliver(rspec_node,
+                            sliver_allocation_dict)
+            geni_slivers.append(geni_sliver)
+
+        logger.debug(" Cortexlabaggregate.PY \tDescribe rspec_nodes %s\
+                        rspec %s "
+                     % (rspec_nodes, rspec))
+        rspec.version.add_nodes(rspec_nodes)
+
+        return {'geni_urn': geni_urn,
+                'geni_rspec': rspec.toxml(),
+                'geni_slivers': geni_slivers}
\ No newline at end of file
index 5fc2604..cd02765 100644 (file)
@@ -1,25 +1,35 @@
 """
 Implements what a driver should provide for SFA to work.
 """
 """
 Implements what a driver should provide for SFA to work.
 """
-from sfa.util.faults import SliverDoesNotExist, UnknownSfaType
+from datetime import datetime
+from sfa.util.sfatime import utcparse, datetime_to_string
+
+from sfa.util.faults import SliverDoesNotExist, Forbidden
 from sfa.util.sfalogging import logger
 from sfa.util.sfalogging import logger
-from sfa.storage.alchemy import dbsession
-from sfa.storage.model import RegRecord
+
+from sfa.trust.hierarchy import Hierarchy
+from sfa.trust.gid import create_uuid
 
 from sfa.managers.driver import Driver
 from sfa.rspecs.version_manager import VersionManager
 from sfa.rspecs.rspec import RSpec
 
 
 from sfa.managers.driver import Driver
 from sfa.rspecs.version_manager import VersionManager
 from sfa.rspecs.rspec import RSpec
 
-from sfa.util.xrn import Xrn, hrn_to_urn, get_authority
-
 from sfa.cortexlab.cortexlabaggregate import CortexlabAggregate, \
             cortexlab_xrn_to_hostname
 
 from sfa.cortexlab.cortexlabslices import CortexlabSlices
 from sfa.cortexlab.cortexlabaggregate import CortexlabAggregate, \
             cortexlab_xrn_to_hostname
 
 from sfa.cortexlab.cortexlabslices import CortexlabSlices
-
 from sfa.cortexlab.cortexlabshell import CortexlabShell
 
 from sfa.cortexlab.cortexlabshell import CortexlabShell
 
+from sfa.iotlab.iotlabxrn import IotlabXrn, xrn_object
+from sfa.util.xrn import Xrn, hrn_to_urn, get_authority, urn_to_hrn
 
 
+from sfa.trust.certificate import Keypair, convert_public_key
+from sfa.trust.credential import Credential
+from sfa.storage.model import SliverAllocation
+
+from sfa.storage.model import RegRecord, RegUser, RegSlice, RegKey
+from sfa.iotlab.iotlabpostgres import LeaseTableXP
+from sqlalchemy.orm import joinedload
 
 class CortexlabDriver(Driver):
     """ Cortexlab Driver class inherited from Driver generic class.
 
 class CortexlabDriver(Driver):
     """ Cortexlab Driver class inherited from Driver generic class.
@@ -30,21 +40,681 @@ class CortexlabDriver(Driver):
     .. seealso::: Driver class
 
     """
     .. seealso::: Driver class
 
     """
-    def __init__(self, config):
+    def __init__(self, api):
         """
 
         """
 
-        Sets the iotlab SFA config parameters,
-            instanciates the testbed api and the iotlab database.
-
-        :param config: iotlab SFA configuration object
-        :type config: Config object
+        Sets the Cortexlab SFA config parameters,
+            instanciates the testbed api.
 
 
+        :param api: SfaApi configuration object. Holds reference to the
+            database.
+        :type api: SfaApi object
         """
         """
-        Driver.__init__(self, config)
-        self.config = config
+
+        Driver.__init__(self, api)
+        self.api = api
+        config = api.config
         self.testbed_shell = CortexlabShell(config)
         self.cache = None
 
         self.testbed_shell = CortexlabShell(config)
         self.cache = None
 
+    def GetPeers(self, peer_filter=None ):
+        """ Gathers registered authorities in SFA DB and looks for specific peer
+        if peer_filter is specified.
+        :param peer_filter: name of the site authority looked for.
+        :type peer_filter: string
+        :returns: list of records.
+
+        """
+
+        existing_records = {}
+        existing_hrns_by_types = {}
+        logger.debug("CORTEXLAB_API \tGetPeers peer_filter %s " % (peer_filter))
+        query = self.api.dbsession().query(RegRecord)
+        all_records = query.filter(RegRecord.type.like('%authority%')).all()
+
+        for record in all_records:
+            existing_records[(record.hrn, record.type)] = record
+            if record.type not in existing_hrns_by_types:
+                existing_hrns_by_types[record.type] = [record.hrn]
+            else:
+                existing_hrns_by_types[record.type].append(record.hrn)
+
+        logger.debug("CORTEXLAB_API \tGetPeer\texisting_hrns_by_types %s "
+                     % (existing_hrns_by_types))
+        records_list = []
+
+        try:
+            if peer_filter:
+                records_list.append(existing_records[(peer_filter,
+                                                     'authority')])
+            else:
+                for hrn in existing_hrns_by_types['authority']:
+                    records_list.append(existing_records[(hrn, 'authority')])
+
+            logger.debug("CORTEXLAB_API \tGetPeer \trecords_list  %s "
+                         % (records_list))
+
+        except KeyError:
+            pass
+
+        return_records = records_list
+        logger.debug("CORTEXLAB_API \tGetPeer return_records %s "
+                     % (return_records))
+        return return_records
+
+    def GetKeys(self, key_filter=None):
+        """Returns a dict of dict based on the key string. Each dict entry
+        contains the key id, the ssh key, the user's email and the
+        user's hrn.
+        If key_filter is specified and is an array of key identifiers,
+        only keys matching the filter will be returned.
+
+        Admin may query all keys. Non-admins may only query their own keys.
+        FROM PLC API DOC
+
+        :returns: dict with ssh key as key and dicts as value.
+        :rtype: dict
+        """
+        query = self.api.dbsession().query(RegKey)
+        if key_filter is None:
+            keys = query.options(joinedload('reg_user')).all()
+        else:
+            constraint = RegKey.key.in_(key_filter)
+            keys = query.options(joinedload('reg_user')).filter(constraint).all()
+
+        key_dict = {}
+        for key in keys:
+            key_dict[key.key] = {'key_id': key.key_id, 'key': key.key,
+                                 'email': key.reg_user.email,
+                                 'hrn': key.reg_user.hrn}
+
+        #ldap_rslt = self.ldap.LdapSearch({'enabled']=True})
+        #user_by_email = dict((user[1]['mail'][0], user[1]['sshPublicKey']) \
+                                        #for user in ldap_rslt)
+
+        logger.debug("CORTEXLAB_API  GetKeys  -key_dict %s \r\n " % (key_dict))
+        return key_dict
+
+    def AddPerson(self, record):
+        """
+
+        Adds a new account. Any fields specified in records are used,
+            otherwise defaults are used. Creates an appropriate login by calling
+            LdapAddUser.
+
+        :param record: dictionary with the sfa user's properties.
+        :returns: a dicitonary with the status. If successful, the dictionary
+            boolean is set to True and there is a 'uid' key with the new login
+            added to LDAP, otherwise the bool is set to False and a key
+            'message' is in the dictionary, with the error message.
+        :rtype: dict
+
+        """
+        ret = self.testbed_shell.ldap.LdapAddUser(record)
+
+        if ret['bool'] is True:
+            record['hrn'] = self.testbed_shell.root_auth + '.' + ret['uid']
+            logger.debug("Cortexlab api AddPerson return code %s record %s  "
+                         % (ret, record))
+            self.__add_person_to_db(record)
+        return ret
+
+    def __add_person_to_db(self, user_dict):
+        """
+        Add a federated user straight to db when the user issues a lease
+        request with nodes and that he has not registered with cortexlab
+        yet (that is he does not have a LDAP entry yet).
+        Uses parts of the routines in CortexlabImport when importing user
+        from LDAP.
+        Called by AddPerson, right after LdapAddUser.
+        :param user_dict: Must contain email, hrn and pkey to get a GID
+        and be added to the SFA db.
+        :type user_dict: dict
+
+        """
+        request = self.api.dbsession().query(RegUser)
+        check_if_exists = \
+            request.filter_by(email = user_dict['email']).first()
+        #user doesn't exists
+        if not check_if_exists:
+            logger.debug("__add_person_to_db \t Adding %s \r\n \r\n \
+                                            " %(user_dict))
+            hrn = user_dict['hrn']
+            person_urn = hrn_to_urn(hrn, 'user')
+            pubkey = user_dict['pkey']
+            try:
+                pkey = convert_public_key(pubkey)
+            except TypeError:
+                #key not good. create another pkey
+                logger.warn('__add_person_to_db: unable to convert public \
+                                    key for %s' %(hrn ))
+                pkey = Keypair(create=True)
+
+
+            if pubkey is not None and pkey is not None :
+                hierarchy = Hierarchy()
+                person_gid = hierarchy.create_gid(person_urn, create_uuid(), \
+                                pkey)
+                if user_dict['email']:
+                    logger.debug("__add_person_to_db \r\n \r\n \
+                        IOTLAB IMPORTER PERSON EMAIL OK email %s "\
+                        %(user_dict['email']))
+                    person_gid.set_email(user_dict['email'])
+
+            user_record = RegUser(hrn=hrn , pointer= '-1', \
+                                    authority=get_authority(hrn), \
+                                    email=user_dict['email'], gid = person_gid)
+            user_record.reg_keys = [RegKey(user_dict['pkey'])]
+            user_record.just_created()
+            self.api.dbsession().add (user_record)
+            self.api.dbsession().commit()
+        return
+
+
+    def _sql_get_slice_info(self, slice_filter):
+        """
+        Get the slice record based on the slice hrn. Fetch the record of the
+        user associated with the slice by using joinedload based on the
+        reg_researcher relationship.
+
+        :param slice_filter: the slice hrn we are looking for
+        :type slice_filter: string
+        :returns: the slice record enhanced with the user's information if the
+            slice was found, None it wasn't.
+
+        :rtype: dict or None.
+        """
+        #DO NOT USE RegSlice - reg_researchers to get the hrn
+        #of the user otherwise will mess up the RegRecord in
+        #Resolve, don't know why - SA 08/08/2012
+
+        #Only one entry for one user  = one slice in testbed_xp table
+        #slicerec = dbsession.query(RegRecord).filter_by(hrn = slice_filter).first()
+        request = self.api.dbsession().query(RegSlice)
+        raw_slicerec = request.options(joinedload('reg_researchers')).filter_by(hrn=slice_filter).first()
+        #raw_slicerec = dbsession.query(RegRecord).filter_by(hrn = slice_filter).first()
+        if raw_slicerec:
+            #load_reg_researcher
+            #raw_slicerec.reg_researchers
+            raw_slicerec = raw_slicerec.__dict__
+            logger.debug(" CORTEXLAB_API \t  _sql_get_slice_info slice_filter %s  \
+                            raw_slicerec %s" % (slice_filter, raw_slicerec))
+            slicerec = raw_slicerec
+            #only one researcher per slice so take the first one
+            #slicerec['reg_researchers'] = raw_slicerec['reg_researchers']
+            #del slicerec['reg_researchers']['_sa_instance_state']
+            return slicerec
+
+        else:
+            return None
+
+    def _sql_get_slice_info_from_user(self, slice_filter):
+        """
+        Get the slice record based on the user recordid by using a joinedload
+        on the relationship reg_slices_as_researcher. Format the sql record
+        into a dict with the mandatory fields for user and slice.
+        :returns: dict with slice record and user record if the record was found
+        based on the user's id, None if not..
+        :rtype:dict or None..
+        """
+        #slicerec = dbsession.query(RegRecord).filter_by(record_id = slice_filter).first()
+        request = self.api.dbsession().query(RegUser)
+        raw_slicerec = request.options(joinedload('reg_slices_as_researcher')).filter_by(record_id=slice_filter).first()
+        #raw_slicerec = dbsession.query(RegRecord).filter_by(record_id = slice_filter).first()
+        #Put it in correct order
+        user_needed_fields = ['peer_authority', 'hrn', 'last_updated',
+                              'classtype', 'authority', 'gid', 'record_id',
+                              'date_created', 'type', 'email', 'pointer']
+        slice_needed_fields = ['peer_authority', 'hrn', 'last_updated',
+                               'classtype', 'authority', 'gid', 'record_id',
+                               'date_created', 'type', 'pointer']
+        if raw_slicerec:
+            #raw_slicerec.reg_slices_as_researcher
+            raw_slicerec = raw_slicerec.__dict__
+            slicerec = {}
+            slicerec = \
+                dict([(k, raw_slicerec[
+                    'reg_slices_as_researcher'][0].__dict__[k])
+                    for k in slice_needed_fields])
+            slicerec['reg_researchers'] = dict([(k, raw_slicerec[k])
+                                                for k in user_needed_fields])
+             #TODO Handle multiple slices for one user SA 10/12/12
+                        #for now only take the first slice record associated to the rec user
+                        ##slicerec  = raw_slicerec['reg_slices_as_researcher'][0].__dict__
+                        #del raw_slicerec['reg_slices_as_researcher']
+                        #slicerec['reg_researchers'] = raw_slicerec
+                        ##del slicerec['_sa_instance_state']
+
+            return slicerec
+
+        else:
+            return None
+
+
+    def _get_slice_records(self, slice_filter=None,
+                           slice_filter_type=None):
+        """
+        Get the slice record depending on the slice filter and its type.
+        :param slice_filter: Can be either the slice hrn or the user's record
+        id.
+        :type slice_filter: string
+        :param slice_filter_type: describes the slice filter type used, can be
+        slice_hrn or record_id_user
+        :type: string
+        :returns: the slice record
+        :rtype:dict
+        .. seealso::_sql_get_slice_info_from_user
+        .. seealso:: _sql_get_slice_info
+        """
+
+        #Get list of slices based on the slice hrn
+        if slice_filter_type == 'slice_hrn':
+
+            #if get_authority(slice_filter) == self.root_auth:
+                #login = slice_filter.split(".")[1].split("_")[0]
+
+            slicerec = self._sql_get_slice_info(slice_filter)
+
+            if slicerec is None:
+                return None
+                #return login, None
+
+        #Get slice based on user id
+        if slice_filter_type == 'record_id_user':
+
+            slicerec = self._sql_get_slice_info_from_user(slice_filter)
+
+        if slicerec:
+            fixed_slicerec_dict = slicerec
+            #At this point if there is no login it means
+            #record_id_user filter has been used for filtering
+            #if login is None :
+                ##If theslice record is from iotlab
+                #if fixed_slicerec_dict['peer_authority'] is None:
+                    #login = fixed_slicerec_dict['hrn'].split(".")[1].split("_")[0]
+            #return login, fixed_slicerec_dict
+            return fixed_slicerec_dict
+        else:
+            return None
+
+
+
+    def GetSlices(self, slice_filter=None, slice_filter_type=None,
+                  login=None):
+        """Get the slice records from the sfa db and add lease information
+            if any.
+
+        :param slice_filter: can be the slice hrn or slice record id in the db
+            depending on the slice_filter_type.
+        :param slice_filter_type: defines the type of the filtering used, Can be
+            either 'slice_hrn' or 'record_id'.
+        :type slice_filter: string
+        :type slice_filter_type: string
+        :returns: a slice dict if slice_filter  and slice_filter_type
+            are specified and a matching entry is found in the db. The result
+            is put into a list.Or a list of slice dictionnaries if no filters
+            arespecified.
+
+        :rtype: list
+
+        """
+        #login = None
+        authorized_filter_types_list = ['slice_hrn', 'record_id_user']
+        return_slicerec_dictlist = []
+
+        #First try to get information on the slice based on the filter provided
+        if slice_filter_type in authorized_filter_types_list:
+            fixed_slicerec_dict = self._get_slice_records(slice_filter,
+                                                          slice_filter_type)
+            # if the slice was not found in the sfa db
+            if fixed_slicerec_dict is None:
+                return return_slicerec_dictlist
+
+            slice_hrn = fixed_slicerec_dict['hrn']
+
+            logger.debug(" CORTEXLAB_API \tGetSlices login %s \
+                            slice record %s slice_filter %s \
+                            slice_filter_type %s " % (login,
+                            fixed_slicerec_dict, slice_filter,
+                            slice_filter_type))
+
+
+            #Now we have the slice record fixed_slicerec_dict, get the
+            #jobs associated to this slice
+            leases_list = []
+
+            leases_list = self.GetLeases(login=login)
+            #If no job is running or no job scheduled
+            #return only the slice record
+            if leases_list == [] and fixed_slicerec_dict:
+                return_slicerec_dictlist.append(fixed_slicerec_dict)
+
+            # if the jobs running don't belong to the user/slice we are looking
+            # for
+            leases_hrn = [lease['slice_hrn'] for lease in leases_list]
+            if slice_hrn not in leases_hrn:
+                return_slicerec_dictlist.append(fixed_slicerec_dict)
+            #If several experiments for one slice , put the slice record into
+            # each lease information dict
+            for lease in leases_list:
+                slicerec_dict = {}
+                logger.debug("CORTEXLAB_API.PY  \tGetSlices slice_filter %s   \
+                        \t lease['slice_hrn'] %s"
+                             % (slice_filter, lease['slice_hrn']))
+                if lease['slice_hrn'] == slice_hrn:
+                    slicerec_dict['experiment_id'] = lease['lease_id']
+                    #Update lease dict with the slice record
+                    if fixed_slicerec_dict:
+                        fixed_slicerec_dict['experiment_id'] = []
+                        fixed_slicerec_dict['experiment_id'].append(
+                            slicerec_dict['experiment_id'])
+                        slicerec_dict.update(fixed_slicerec_dict)
+
+                    slicerec_dict['slice_hrn'] = lease['slice_hrn']
+                    slicerec_dict['hrn'] = lease['slice_hrn']
+                    slicerec_dict['user'] = lease['user']
+                    slicerec_dict.update(
+                        {'list_node_ids':
+                        {'hostname': lease['reserved_nodes']}})
+                    slicerec_dict.update({'node_ids': lease['reserved_nodes']})
+
+
+                    return_slicerec_dictlist.append(slicerec_dict)
+
+
+                logger.debug("CORTEXLAB_API.PY  \tGetSlices  \
+                        slicerec_dict %s return_slicerec_dictlist %s \
+                        lease['reserved_nodes'] \
+                        %s" % (slicerec_dict, return_slicerec_dictlist,
+                               lease['reserved_nodes']))
+
+            logger.debug("CORTEXLAB_API.PY  \tGetSlices  RETURN \
+                        return_slicerec_dictlist  %s"
+                          % (return_slicerec_dictlist))
+
+            return return_slicerec_dictlist
+
+
+        else:
+            #Get all slices from the cortexlab sfa database , get the user info
+            # as well at the same time put them in dict format
+            request = self.api.dbsession().query(RegSlice)
+            query_slice_list = \
+                request.options(joinedload('reg_researchers')).all()
+
+            for record in query_slice_list:
+                tmp = record.__dict__
+                tmp['reg_researchers'] = tmp['reg_researchers'][0].__dict__
+                return_slicerec_dictlist.append(tmp)
+
+
+            #Get all the experiments reserved nodes
+            leases_list = self.testbed_shell.GetReservedNodes()
+
+            for fixed_slicerec_dict in return_slicerec_dictlist:
+                slicerec_dict = {}
+                #Check if the slice belongs to a cortexlab user
+                if fixed_slicerec_dict['peer_authority'] is None:
+                    owner = fixed_slicerec_dict['hrn'].split(
+                        ".")[1].split("_")[0]
+                else:
+                    owner = None
+                for lease in leases_list:
+                    if owner == lease['user']:
+                        slicerec_dict['experiment_id'] = lease['lease_id']
+
+                        #for reserved_node in lease['reserved_nodes']:
+                        logger.debug("CORTEXLAB_API.PY  \tGetSlices lease %s "
+                                     % (lease))
+                        slicerec_dict.update(fixed_slicerec_dict)
+                        slicerec_dict.update({'node_ids':
+                                              lease['reserved_nodes']})
+                        slicerec_dict.update({'list_node_ids':
+                                             {'hostname':
+                                             lease['reserved_nodes']}})
+
+
+                        fixed_slicerec_dict.update(slicerec_dict)
+
+            logger.debug("CORTEXLAB_API.PY  \tGetSlices RETURN \
+                        return_slicerec_dictlist %s \t slice_filter %s " \
+                        %(return_slicerec_dictlist, slice_filter))
+
+        return return_slicerec_dictlist
+
+    def AddLeases(self, hostname_list, slice_record,
+                  lease_start_time, lease_duration):
+
+        """Creates an experiment on the testbed corresponding to the information
+        provided as parameters. Adds the experiment id and the slice hrn in the
+        lease table on the additional sfa database so that we are able to know
+        which slice has which nodes.
+
+        :param hostname_list: list of nodes' OAR hostnames.
+        :param slice_record: sfa slice record, must contain login and hrn.
+        :param lease_start_time: starting time , unix timestamp format
+        :param lease_duration: duration in minutes
+
+        :type hostname_list: list
+        :type slice_record: dict
+        :type lease_start_time: integer
+        :type lease_duration: integer
+        :returns: experiment_id, can be None if the job request failed.
+
+        """
+        logger.debug("CORTEXLAB_API \r\n \r\n \t AddLeases hostname_list %s  \
+                slice_record %s lease_start_time %s lease_duration %s  "\
+                 %( hostname_list, slice_record , lease_start_time, \
+                 lease_duration))
+
+        username = slice_record['login']
+
+        experiment_id = self.testbed_shell.LaunchExperimentOnTestbed(
+                                    hostname_list,
+                                    slice_record['hrn'],
+                                    lease_start_time, lease_duration,
+                                    username)
+        if experiment_id is not None:
+            start_time = \
+                    datetime.fromtimestamp(int(lease_start_time)).\
+                    strftime(self.testbed_shell.time_format)
+            end_time = lease_start_time + lease_duration
+
+
+            logger.debug("CORTEXLAB_API \t AddLeases TURN ON LOGGING SQL \
+                    %s %s %s "%(slice_record['hrn'], experiment_id, end_time))
+
+
+            logger.debug("CORTEXLAB_API \r\n \r\n \t AddLeases %s %s %s " \
+                %(type(slice_record['hrn']), type(experiment_id),
+                type(end_time)))
+
+            testbed_xp_row = LeaseTableXP(slice_hrn=slice_record['hrn'],
+                                            experiment_id=experiment_id,
+                                            end_time=end_time)
+
+            logger.debug("CORTEXLAB_API  \t AddLeases testbed_xp_row %s" \
+                %(testbed_xp_row))
+            self.api.dbsession().add(testbed_xp_row)
+            self.api.dbsession().commit()
+
+            logger.debug("CORTEXLAB_API \t AddLeases hostname_list \
+                    start_time %s " %(start_time))
+
+        return experiment_id
+
+
+    def GetLeases(self, lease_filter_dict=None, login=None):
+        """
+        Get the list of leases from testbed with complete information
+            about which slice owns which jobs and nodes.
+            Two purposes:
+            -Fetch all the experiment from the testbed (running, waiting..)
+            complete the reservation information with slice hrn
+            found in lease_table . If not available in the table,
+            assume it is a iotlab slice.
+            -Updates the iotlab table, deleting jobs when necessary.
+
+        :returns: reservation_list, list of dictionaries with 'lease_id',
+            'reserved_nodes','slice_id', 'state', 'user', 'component_id_list',
+            'slice_hrn', 'resource_ids', 't_from', 't_until'
+        :rtype: list
+
+        """
+
+        unfiltered_reservation_list = self.testbed_shell.GetReservedNodes(login)
+
+        reservation_list = []
+        #Find the slice associated with this user iotlab ldap uid
+        logger.debug(" CORTEXLAB \tGetLeases login %s\
+                        unfiltered_reservation_list %s "
+                     % (login, unfiltered_reservation_list))
+        #Create user dict first to avoid looking several times for
+        #the same user in LDAP SA 27/07/12
+        experiment_id_list = []
+        jobs_psql_query = self.api.dbsession().query(LeaseTableXP).all()
+        jobs_psql_dict = dict([(row.experiment_id, row.__dict__)
+                               for row in jobs_psql_query])
+        #jobs_psql_dict = jobs_psql_dict)
+        logger.debug("CORTEXLAB \tGetLeases jobs_psql_dict %s"
+                     % (jobs_psql_dict))
+        jobs_psql_id_list = [row.experiment_id for row in jobs_psql_query]
+
+        for resa in unfiltered_reservation_list:
+            logger.debug("CORTEXLAB \tGetLeases USER %s"
+                         % (resa['user']))
+            #Construct list of jobs (runing, waiting..) from scheduler
+            experiment_id_list.append(resa['lease_id'])
+            #If there is information on the job in IOTLAB DB ]
+            #(slice used and job id)
+            if resa['lease_id'] in jobs_psql_dict:
+                job_info = jobs_psql_dict[resa['lease_id']]
+                logger.debug("CORTEXLAB \tGetLeases job_info %s"
+                          % (job_info))
+                resa['slice_hrn'] = job_info['slice_hrn']
+                resa['slice_id'] = hrn_to_urn(resa['slice_hrn'], 'slice')
+
+            #otherwise, assume it is a iotlab slice:
+            else:
+                resa['slice_id'] = hrn_to_urn(self.testbed_shell.root_auth \
+                                            + '.' + resa['user'] + "_slice",
+                                            'slice')
+                resa['slice_hrn'] = Xrn(resa['slice_id']).get_hrn()
+
+            resa['component_id_list'] = []
+            #Transform the hostnames into urns (component ids)
+            for node in resa['reserved_nodes']:
+
+                iotlab_xrn = xrn_object(self.testbed_shell.root_auth, node)
+                resa['component_id_list'].append(iotlab_xrn.urn)
+
+        if lease_filter_dict:
+            logger.debug("CORTEXLAB \tGetLeases  \
+                    \r\n leasefilter %s" % ( lease_filter_dict))
+
+            # filter_dict_functions = {
+            # 'slice_hrn' : IotlabShell.filter_lease_name,
+            # 't_from' : IotlabShell.filter_lease_start_time
+            # }
+            reservation_list = list(unfiltered_reservation_list)
+            for filter_type in lease_filter_dict:
+                logger.debug("CORTEXLAB \tGetLeases reservation_list %s" \
+                    % (reservation_list))
+                reservation_list = self.testbed_shell.filter_lease(
+                        reservation_list,filter_type,
+                        lease_filter_dict[filter_type] )
+
+                # Filter the reservation list with a maximum timespan so that the
+                # leases and jobs running after this timestamp do not appear
+                # in the result leases.
+                # if 'start_time' in :
+                #     if resa['start_time'] < lease_filter_dict['start_time']:
+                #        reservation_list.append(resa)
+
+
+                # if 'name' in lease_filter_dict and \
+                #     lease_filter_dict['name'] == resa['slice_hrn']:
+                #     reservation_list.append(resa)
+
+
+        if lease_filter_dict is None:
+            reservation_list = unfiltered_reservation_list
+
+        self.update_experiments_in_lease_table(experiment_id_list,
+                                                    jobs_psql_id_list)
+
+        logger.debug(" CORTEXLAB.PY \tGetLeases reservation_list %s"
+                     % (reservation_list))
+        return reservation_list
+
+    def update_experiments_in_lease_table(self,
+        experiment_list_from_testbed, experiment_list_in_db):
+        """Cleans the lease_table by deleting expired and cancelled jobs.
+
+        Compares the list of experiment ids given by the testbed with the
+        experiment ids that are already in the database, deletes the
+        experiments that are no longer in the testbed experiment id list.
+
+        :param  experiment_list_from_testbed: list of experiment ids coming
+            from testbed
+        :type experiment_list_from_testbed: list
+        :param experiment_list_in_db: list of experiment ids from the sfa
+            additionnal database.
+        :type experiment_list_in_db: list
+
+        :returns: None
+        """
+        #Turn the list into a set
+        set_experiment_list_in_db = set(experiment_list_in_db)
+
+        kept_experiments = set(experiment_list_from_testbed).intersection(set_experiment_list_in_db)
+        logger.debug("\r\n \t update_experiments_in_lease_table \
+                        experiment_list_in_db %s \r\n \
+                        experiment_list_from_testbed %s \
+                        kept_experiments %s "
+                     % (set_experiment_list_in_db,
+                      experiment_list_from_testbed, kept_experiments))
+        deleted_experiments = set_experiment_list_in_db.difference(
+            kept_experiments)
+        deleted_experiments = list(deleted_experiments)
+        if len(deleted_experiments) > 0:
+            request = self.api.dbsession().query(LeaseTableXP)
+            request.filter(LeaseTableXP.experiment_id.in_(deleted_experiments)).delete(synchronize_session='fetch')
+            self.api.dbsession().commit()
+        return
+
+
+    def AddSlice(self, slice_record, user_record):
+        """
+
+        Add slice to the local cortexlab sfa tables if the slice comes
+            from a federated site and is not yet in the cortexlab sfa DB,
+            although the user has already a LDAP login.
+            Called by verify_slice during lease/sliver creation.
+
+        :param slice_record: record of slice, must contain hrn, gid, slice_id
+            and authority of the slice.
+        :type slice_record: dictionary
+        :param user_record: record of the user
+        :type user_record: RegUser
+
+        """
+
+        sfa_record = RegSlice(hrn=slice_record['hrn'],
+                              gid=slice_record['gid'],
+                              pointer=slice_record['slice_id'],
+                              authority=slice_record['authority'])
+        logger.debug("CORTEXLAB_API.PY AddSlice  sfa_record %s user_record %s"
+                     % (sfa_record, user_record))
+        sfa_record.just_created()
+        self.api.dbsession().add(sfa_record)
+        self.api.dbsession().commit()
+        #Update the reg-researcher dependance table
+        sfa_record.reg_researchers = [user_record]
+        self.api.dbsession().commit()
+
+        return
+
     def augment_records_with_testbed_info(self, record_list):
         """
 
     def augment_records_with_testbed_info(self, record_list):
         """
 
@@ -118,8 +788,8 @@ class CortexlabDriver(Driver):
                                 # For client_helper.py compatibility
                              'key_ids': ''})
 
                                 # For client_helper.py compatibility
                              'key_ids': ''})
 
-                    #Get iotlab slice record and oar job id if any.
-                    recslice_list = self.testbed_shell.GetSlices(
+                    #Get  slice record and  job id if any.
+                    recslice_list = self.GetSlices(
                         slice_filter=str(record['hrn']),
                         slice_filter_type='slice_hrn')
 
                         slice_filter=str(record['hrn']),
                         slice_filter_type='slice_hrn')
 
@@ -147,7 +817,7 @@ class CortexlabDriver(Driver):
                     #The record is a SFA user record.
                     #Get the information about his slice from Iotlab's DB
                     #and add it to the user record.
                     #The record is a SFA user record.
                     #Get the information about his slice from Iotlab's DB
                     #and add it to the user record.
-                    recslice_list = self.testbed_shell.GetSlices(
+                    recslice_list = self.GetSlices(
                         slice_filter=record['record_id'],
                         slice_filter_type='record_id_user')
 
                         slice_filter=record['record_id'],
                         slice_filter_type='record_id_user')
 
@@ -166,7 +836,7 @@ class CortexlabDriver(Driver):
                     recslice.update(
                         {'PI': [recuser['hrn']],
                          'researcher': [recuser['hrn']],
                     recslice.update(
                         {'PI': [recuser['hrn']],
                          'researcher': [recuser['hrn']],
-                         'name': record['hrn'],
+                         'name': recuser['hrn'],
                          'node_ids': [],
                          'experiment_id': [],
                          'person_ids': [recuser['record_id']]})
                          'node_ids': [],
                          'experiment_id': [],
                          'person_ids': [recuser['record_id']]})
@@ -216,7 +886,7 @@ class CortexlabDriver(Driver):
         """
 
         #First get the slice with the slice hrn
         """
 
         #First get the slice with the slice hrn
-        slice_list = self.testbed_shell.GetSlices(slice_filter=slice_hrn,
+        slice_list = self.GetSlices(slice_filter=slice_hrn,
                                                slice_filter_type='slice_hrn')
 
         if len(slice_list) == 0:
                                                slice_filter_type='slice_hrn')
 
         if len(slice_list) == 0:
@@ -294,7 +964,6 @@ class CortexlabDriver(Driver):
                          % (resources, res))
             return result
 
                          % (resources, res))
             return result
 
-
     def get_user_record(self, hrn):
         """
 
     def get_user_record(self, hrn):
         """
 
@@ -306,7 +975,7 @@ class CortexlabDriver(Driver):
         :rtype: RegUser
 
         """
         :rtype: RegUser
 
         """
-        return dbsession.query(RegRecord).filter_by(hrn=hrn).first()
+        return self.api.dbsession().query(RegRecord).filter_by(hrn=hrn).first()
 
     def testbed_name(self):
         """
 
     def testbed_name(self):
         """
@@ -318,28 +987,6 @@ class CortexlabDriver(Driver):
         """
         return self.hrn
 
         """
         return self.hrn
 
-    # 'geni_request_rspec_versions' and 'geni_ad_rspec_versions' are mandatory
-    def aggregate_version(self):
-        """
-
-        Returns the testbed's supported rspec advertisement and request
-        versions.
-        :returns: rspec versions supported ad a dictionary.
-        :rtype: dict
-
-        """
-        version_manager = VersionManager()
-        ad_rspec_versions = []
-        request_rspec_versions = []
-        for rspec_version in version_manager.versions:
-            if rspec_version.content_type in ['*', 'ad']:
-                ad_rspec_versions.append(rspec_version.to_dict())
-            if rspec_version.content_type in ['*', 'request']:
-                request_rspec_versions.append(rspec_version.to_dict())
-        return {
-            'testbed': self.testbed_name(),
-            'geni_request_rspec_versions': request_rspec_versions,
-            'geni_ad_rspec_versions': ad_rspec_versions}
 
     def _get_requested_leases_list(self, rspec):
         """
 
     def _get_requested_leases_list(self, rspec):
         """
@@ -413,6 +1060,7 @@ class CortexlabDriver(Driver):
 
         return requested_xp_dict
 
 
         return requested_xp_dict
 
+
     def _process_requested_xp_dict(self, rspec):
         """
         Turns the requested leases and information into a dictionary
     def _process_requested_xp_dict(self, rspec):
         """
         Turns the requested leases and information into a dictionary
@@ -432,106 +1080,16 @@ class CortexlabDriver(Driver):
 
         return xp_dict
 
 
         return xp_dict
 
-    def create_sliver(self, slice_urn, slice_hrn, creds, rspec_string,
-                      users, options):
-        """Answer to CreateSliver.
-
-        Creates the leases and slivers for the users from the information
-            found in the rspec string.
-            Launch experiment on OAR if the requested leases is valid. Delete
-            no longer requested leases.
-
-
-        :param creds: user's credentials
-        :type creds: string
-        :param users: user record list
-        :type users: list
-        :param options:
-        :type options:
-
-        :returns: a valid Rspec for the slice which has just been
-            modified.
-        :rtype: RSpec
 
 
 
 
-        """
-        aggregate = CortexlabAggregate(self)
-
-        slices = CortexlabSlices(self)
-        peer = slices.get_peer(slice_hrn)
-        sfa_peer = slices.get_sfa_peer(slice_hrn)
-        slice_record = None
-
-        if not isinstance(creds, list):
-            creds = [creds]
-
-        if users:
-            slice_record = users[0].get('slice_record', {})
-            logger.debug("CORTEXLABDRIVER.PY \t ===============create_sliver \t\
-                            creds %s \r\n \r\n users %s"
-                         % (creds, users))
-            slice_record['user'] = {'keys': users[0]['keys'],
-                                    'email': users[0]['email'],
-                                    'hrn': slice_record['reg-researchers'][0]}
-        # parse rspec
-        rspec = RSpec(rspec_string)
-        logger.debug("CORTEXLABDRIVER.PY \t create_sliver \trspec.version \
-                     %s slice_record %s users %s"
-                     % (rspec.version, slice_record, users))
-
-        # ensure site record exists?
-        # ensure slice record exists
-        #Removed options in verify_slice SA 14/08/12
-        #Removed peer record in  verify_slice SA 18/07/13
-        sfa_slice = slices.verify_slice(slice_hrn, slice_record, sfa_peer)
-
-        # ensure person records exists
-        #verify_persons returns added persons but the return value
-        #is not used
-        #Removed peer record and sfa_peer in  verify_persons SA 18/07/13
-        slices.verify_persons(slice_hrn, sfa_slice, users, options=options)
-        #requested_attributes returned by rspec.version.get_slice_attributes()
-        #unused, removed SA 13/08/12
-        #rspec.version.get_slice_attributes()
-
-        logger.debug("CORTEXLABDRIVER.PY create_sliver slice %s " % (sfa_slice))
-
-        # add/remove slice from nodes
-
-        #requested_slivers = [node.get('component_id') \
-                    #for node in rspec.version.get_nodes_with_slivers()\
-                    #if node.get('authority_id') is self.testbed_shell.root_auth]
-        #l = [ node for node in rspec.version.get_nodes_with_slivers() ]
-        #logger.debug("SLADRIVER \tcreate_sliver requested_slivers \
-                                    #requested_slivers %s  listnodes %s" \
-                                    #%(requested_slivers,l))
-        #verify_slice_nodes returns nodes, but unused here. Removed SA 13/08/12.
-        #slices.verify_slice_nodes(sfa_slice, requested_slivers, peer)
-
-        requested_xp_dict = self._process_requested_xp_dict(rspec)
-
-        logger.debug("CORTEXLABDRIVER.PY \tcreate_sliver  requested_xp_dict %s "
-                     % (requested_xp_dict))
-        #verify_slice_leases returns the leases , but the return value is unused
-        #here. Removed SA 13/08/12
-        slices.verify_slice_leases(sfa_slice,
-                                   requested_xp_dict, peer)
-
-        return aggregate.get_rspec(slice_xrn=slice_urn,
-                                   login=sfa_slice['login'],
-                                   version=rspec.version)
-
-    def delete_sliver(self, slice_urn, slice_hrn, creds, options):
+    def delete(self, slice_urns, options={}):
         """
         Deletes the lease associated with the slice hrn and the credentials
             if the slice belongs to iotlab. Answer to DeleteSliver.
 
         :param slice_urn: urn of the slice
         """
         Deletes the lease associated with the slice hrn and the credentials
             if the slice belongs to iotlab. Answer to DeleteSliver.
 
         :param slice_urn: urn of the slice
-        :param slice_hrn: name of the slice
-        :param creds: slice credenials
         :type slice_urn: string
         :type slice_urn: string
-        :type slice_hrn: string
-        :type creds: ? unused
+
 
         :returns: 1 if the slice to delete was not found on iotlab,
             True if the deletion was successful, False otherwise otherwise.
 
         :returns: 1 if the slice to delete was not found on iotlab,
             True if the deletion was successful, False otherwise otherwise.
@@ -542,17 +1100,34 @@ class CortexlabDriver(Driver):
         .. note:: creds are unused, and are not used either in the dummy driver
              delete_sliver .
         """
         .. note:: creds are unused, and are not used either in the dummy driver
              delete_sliver .
         """
-
-        sfa_slice_list = self.testbed_shell.GetSlices(
-            slice_filter=slice_hrn,
-            slice_filter_type='slice_hrn')
+        # collect sliver ids so we can update sliver allocation states after
+        # we remove the slivers.
+        aggregate = CortexlabAggregate(self)
+        slivers = aggregate.get_slivers(slice_urns)
+        if slivers:
+            # slice_id = slivers[0]['slice_id']
+            node_ids = []
+            sliver_ids = []
+            sliver_jobs_dict = {}
+            for sliver in slivers:
+                node_ids.append(sliver['node_id'])
+                sliver_ids.append(sliver['sliver_id'])
+                job_id = sliver['sliver_id'].split('+')[-1].split('-')[0]
+                sliver_jobs_dict[job_id] = sliver['sliver_id']
+        logger.debug("CORTEXLABDRIVER.PY delete_sliver slivers %s slice_urns %s"
+            % (slivers, slice_urns))
+        slice_hrn = urn_to_hrn(slice_urns[0])[0]
+
+        sfa_slice_list = self.GetSlices(slice_filter=slice_hrn,
+                                        slice_filter_type='slice_hrn')
 
         if not sfa_slice_list:
             return 1
 
         #Delete all leases in the slice
         for sfa_slice in sfa_slice_list:
 
         if not sfa_slice_list:
             return 1
 
         #Delete all leases in the slice
         for sfa_slice in sfa_slice_list:
-            logger.debug("CORTEXLABDRIVER.PY delete_sliver slice %s" % (sfa_slice))
+            logger.debug("CORTEXLABDRIVER.PY delete_sliver slice %s" \
+                % (sfa_slice))
             slices = CortexlabSlices(self)
             # determine if this is a peer slice
 
             slices = CortexlabSlices(self)
             # determine if this is a peer slice
 
@@ -560,80 +1135,29 @@ class CortexlabDriver(Driver):
 
             logger.debug("CORTEXLABDRIVER.PY delete_sliver peer %s \
                 \r\n \t sfa_slice %s " % (peer, sfa_slice))
 
             logger.debug("CORTEXLABDRIVER.PY delete_sliver peer %s \
                 \r\n \t sfa_slice %s " % (peer, sfa_slice))
+            testbed_bool_ans = self.testbed_shell.DeleteSliceFromNodes(sfa_slice)
+            for job_id in testbed_bool_ans:
+                # if the job has not been successfully deleted
+                # don't delete the associated sliver
+                # remove it from the sliver list
+                if testbed_bool_ans[job_id] is False:
+                    sliver = sliver_jobs_dict[job_id]
+                    sliver_ids.remove(sliver)
             try:
             try:
-                self.testbed_shell.DeleteSliceFromNodes(sfa_slice)
-                return True
-            except:
-                return False
-
-    def list_resources (self, slice_urn, slice_hrn, creds, options):
-        """
-
-        List resources from the iotlab aggregate and returns a Rspec
-            advertisement with resources found when slice_urn and slice_hrn are
-            None (in case of resource discovery).
-            If a slice hrn and urn are provided, list experiment's slice
-            nodes in a rspec format. Answer to ListResources.
-            Caching unused.
-
-        :param slice_urn: urn of the slice
-        :param slice_hrn: name of the slice
-        :param creds: slice credenials
-        :type slice_urn: string
-        :type slice_hrn: string
-        :type creds: ? unused
-        :param options: options used when listing resources (list_leases, info,
-            geni_available)
-        :returns: rspec string in xml
-        :rtype: string
-
-        .. note:: creds are unused
-        """
-
-        #cached_requested = options.get('cached', True)
-
-        version_manager = VersionManager()
-        # get the rspec's return format from options
-        rspec_version = \
-            version_manager.get_version(options.get('geni_rspec_version'))
-        version_string = "rspec_%s" % (rspec_version)
-
-        #panos adding the info option to the caching key (can be improved)
-        if options.get('info'):
-            version_string = version_string + "_" + \
-                options.get('info', 'default')
-
-        # Adding the list_leases option to the caching key
-        if options.get('list_leases'):
-            version_string = version_string + "_" + \
-            options.get('list_leases', 'default')
-
-        # Adding geni_available to caching key
-        if options.get('geni_available'):
-            version_string = version_string + "_" + \
-                str(options.get('geni_available'))
-
-        # look in cache first
-        #if cached_requested and self.cache and not slice_hrn:
-            #rspec = self.cache.get(version_string)
-            #if rspec:
-                #logger.debug("IotlabDriver.ListResources: \
-                                    #returning cached advertisement")
-                #return rspec
-
-        #panos: passing user-defined options
-        aggregate = CortexlabAggregate(self)
 
 
-        rspec = aggregate.get_rspec(slice_xrn=slice_urn,
-                                    version=rspec_version, options=options)
-
-        # cache the result
-        #if self.cache and not slice_hrn:
-            #logger.debug("Iotlab.ListResources: stores advertisement in cache")
-            #self.cache.add(version_string, rspec)
-
-        return rspec
+                dbsession = self.api.dbsession()
+                SliverAllocation.delete_allocations(sliver_ids, dbsession)
+            except :
+                logger.log_exc("CORTEXLABDRIVER.PY delete error ")
 
 
+        # prepare return struct
+        geni_slivers = []
+        for sliver in slivers:
+            geni_slivers.append(
+                {'geni_sliver_urn': sliver['sliver_id'],
+                 'geni_allocation_status': 'geni_unallocated',
+                 'geni_expires': datetime_to_string(utcparse(sliver['expires']))})
+        return geni_slivers
 
     def list_slices(self, creds, options):
         """Answer to ListSlices.
 
     def list_slices(self, creds, options):
         """Answer to ListSlices.
@@ -645,7 +1169,7 @@ class CortexlabDriver(Driver):
         :returns: slice urns list
         :rtype: list
 
         :returns: slice urns list
         :rtype: list
 
-        .. note:: creds are unused
+        .. note:: creds are unused- SA 12/12/13
         """
         # look in cache first
         #if self.cache:
         """
         # look in cache first
         #if self.cache:
@@ -656,7 +1180,7 @@ class CortexlabDriver(Driver):
 
         # get data from db
 
 
         # get data from db
 
-        slices = self.testbed_shell.GetSlices()
+        slices = self.GetSlices()
         logger.debug("CORTEXLABDRIVER.PY \tlist_slices hrn %s \r\n \r\n"
                      % (slices))
         slice_hrns = [iotlab_slice['hrn'] for iotlab_slice in slices]
         logger.debug("CORTEXLABDRIVER.PY \tlist_slices hrn %s \r\n \r\n"
                      % (slices))
         slice_hrns = [iotlab_slice['hrn'] for iotlab_slice in slices]
@@ -694,13 +1218,12 @@ class CortexlabDriver(Driver):
         """
         return -1
 
         """
         return -1
 
-
     def update(self, old_sfa_record, new_sfa_record, hrn, new_key):
         """
     def update(self, old_sfa_record, new_sfa_record, hrn, new_key):
         """
-        No site or node record update allowed in Cortexlab. The only modifications
+        No site or node record update allowed in Iotlab. The only modifications
         authorized here are key deletion/addition on an existing user and
         password change. On an existing user, CAN NOT BE MODIFIED: 'first_name',
         authorized here are key deletion/addition on an existing user and
         password change. On an existing user, CAN NOT BE MODIFIED: 'first_name',
-        'last_name', 'email'. DOES NOT EXIST IN LDAP: 'phone', 'url', 'bio',
+        'last_name', 'email'. DOES NOT EXIST IN SENSLAB: 'phone', 'url', 'bio',
         'title', 'accepted_aup'. A slice is bound to its user, so modifying the
         user's ssh key should nmodify the slice's GID after an import procedure.
 
         'title', 'accepted_aup'. A slice is bound to its user, so modifying the
         user's ssh key should nmodify the slice's GID after an import procedure.
 
@@ -714,48 +1237,52 @@ class CortexlabDriver(Driver):
         :type hrn: string
 
         TODO: needs review
         :type hrn: string
 
         TODO: needs review
-        .. seealso:: update in driver.py.
-
-        """
-        pointer = old_sfa_record['pointer']
-        old_sfa_record_type = old_sfa_record['type']
-
-        # new_key implemented for users only
-        if new_key and old_sfa_record_type not in ['user']:
-            raise UnknownSfaType(old_sfa_record_type)
-
-        if old_sfa_record_type == "user":
-            update_fields = {}
-            all_fields = new_sfa_record
-            for key in all_fields.keys():
-                if key in ['key', 'password']:
-                    update_fields[key] = all_fields[key]
-
-            if new_key:
-                # must check this key against the previous one if it exists
-                persons = self.testbed_shell.GetPersons([old_sfa_record])
-                person = persons[0]
-                keys = [person['pkey']]
-                #Get all the person's keys
-                keys_dict = self.testbed_shell.GetKeys(keys)
-
-                # Delete all stale keys, meaning the user has only one key
-                #at a time
-                #TODO: do we really want to delete all the other keys?
-                #Is this a problem with the GID generation to have multiple
-                #keys? SA 30/05/13
-                key_exists = False
-                if key in keys_dict:
-                    key_exists = True
-                else:
-                    #remove all the other keys
-                    for key in keys_dict:
-                        self.testbed_shell.DeleteKey(person, key)
-                    self.testbed_shell.AddPersonKey(
-                        person, {'sshPublicKey': person['pkey']},
-                        {'sshPublicKey': new_key})
+        .. warning:: SA 12/12/13 - Removed. should be done in iotlabimporter
+        since users, keys and slice are managed by the LDAP.
+
+        """
+        # pointer = old_sfa_record['pointer']
+        # old_sfa_record_type = old_sfa_record['type']
+
+        # # new_key implemented for users only
+        # if new_key and old_sfa_record_type not in ['user']:
+        #     raise UnknownSfaType(old_sfa_record_type)
+
+        # if old_sfa_record_type == "user":
+        #     update_fields = {}
+        #     all_fields = new_sfa_record
+        #     for key in all_fields.keys():
+        #         if key in ['key', 'password']:
+        #             update_fields[key] = all_fields[key]
+
+        #     if new_key:
+        #         # must check this key against the previous one if it exists
+        #         persons = self.testbed_shell.GetPersons([old_sfa_record])
+        #         person = persons[0]
+        #         keys = [person['pkey']]
+        #         #Get all the person's keys
+        #         keys_dict = self.GetKeys(keys)
+
+        #         # Delete all stale keys, meaning the user has only one key
+        #         #at a time
+        #         #TODO: do we really want to delete all the other keys?
+        #         #Is this a problem with the GID generation to have multiple
+        #         #keys? SA 30/05/13
+        #         key_exists = False
+        #         if key in keys_dict:
+        #             key_exists = True
+        #         else:
+        #             #remove all the other keys
+        #             for key in keys_dict:
+        #                 self.testbed_shell.DeleteKey(person, key)
+        #             self.testbed_shell.AddPersonKey(
+        #                 person, {'sshPublicKey': person['pkey']},
+        #                 {'sshPublicKey': new_key})
+        logger.warning ("UNDEFINED - Update should be done by the \
+            iotlabimporter")
         return True
 
         return True
 
+
     def remove(self, sfa_record):
         """
 
     def remove(self, sfa_record):
         """
 
@@ -789,7 +1316,200 @@ class CortexlabDriver(Driver):
                 return self.testbed_shell.DeletePerson(sfa_record)
 
         elif sfa_record_type == 'slice':
                 return self.testbed_shell.DeletePerson(sfa_record)
 
         elif sfa_record_type == 'slice':
-            if self.testbed_shell.GetSlices(slice_filter=hrn,
-                                         slice_filter_type='slice_hrn'):
+            if self.GetSlices(slice_filter=hrn,
+                                slice_filter_type='slice_hrn'):
                 ret = self.testbed_shell.DeleteSlice(sfa_record)
             return True
                 ret = self.testbed_shell.DeleteSlice(sfa_record)
             return True
+
+    def check_sliver_credentials(self, creds, urns):
+        """Check that the sliver urns belongs to the slice specified in the
+        credentials.
+
+        :param urns: list of sliver urns.
+        :type urns: list.
+        :param creds: slice credentials.
+        :type creds: Credential object.
+
+
+        """
+        # build list of cred object hrns
+        slice_cred_names = []
+        for cred in creds:
+            slice_cred_hrn = Credential(cred=cred).get_gid_object().get_hrn()
+            slicename = IotlabXrn(xrn=slice_cred_hrn).iotlab_slicename()
+            slice_cred_names.append(slicename)
+
+        # look up slice name of slivers listed in urns arg
+
+        slice_ids = []
+        for urn in urns:
+            sliver_id_parts = Xrn(xrn=urn).get_sliver_id_parts()
+            try:
+                slice_ids.append(int(sliver_id_parts[0]))
+            except ValueError:
+                pass
+
+        if not slice_ids:
+            raise Forbidden("sliver urn not provided")
+
+        slices = self.GetSlices(slice_ids)
+        sliver_names = [single_slice['name'] for single_slice in slices]
+
+        # make sure we have a credential for every specified sliver
+        for sliver_name in sliver_names:
+            if sliver_name not in slice_cred_names:
+                msg = "Valid credential not found for target: %s" % sliver_name
+                raise Forbidden(msg)
+
+    ########################################
+    ########## aggregate oriented
+    ########################################
+
+    # 'geni_request_rspec_versions' and 'geni_ad_rspec_versions' are mandatory
+    def aggregate_version(self):
+        """
+
+        Returns the testbed's supported rspec advertisement and request
+        versions.
+        :returns: rspec versions supported ad a dictionary.
+        :rtype: dict
+
+        """
+        version_manager = VersionManager()
+        ad_rspec_versions = []
+        request_rspec_versions = []
+        for rspec_version in version_manager.versions:
+            if rspec_version.content_type in ['*', 'ad']:
+                ad_rspec_versions.append(rspec_version.to_dict())
+            if rspec_version.content_type in ['*', 'request']:
+                request_rspec_versions.append(rspec_version.to_dict())
+        return {
+            'testbed': self.testbed_name(),
+            'geni_request_rspec_versions': request_rspec_versions,
+            'geni_ad_rspec_versions': ad_rspec_versions}
+
+
+
+    # first 2 args are None in case of resource discovery
+    def list_resources (self, version=None, options={}):
+        aggregate = CortexlabAggregate(self)
+        rspec =  aggregate.list_resources(version=version, options=options)
+        return rspec
+
+
+    def describe(self, urns, version, options={}):
+        aggregate = CortexlabAggregate(self)
+        return aggregate.describe(urns, version=version, options=options)
+
+    def status (self, urns, options={}):
+        aggregate = CortexlabAggregate(self)
+        desc =  aggregate.describe(urns, version='GENI 3')
+        status = {'geni_urn': desc['geni_urn'],
+                  'geni_slivers': desc['geni_slivers']}
+        return status
+
+
+    def allocate (self, urn, rspec_string, expiration, options={}):
+        xrn = Xrn(urn)
+        aggregate = CortexlabAggregate(self)
+
+        slices = CortexlabSlices(self)
+        peer = slices.get_peer(xrn.get_hrn())
+        sfa_peer = slices.get_sfa_peer(xrn.get_hrn())
+
+        slice_record = None
+        users = options.get('geni_users', [])
+
+        sfa_users = options.get('sfa_users', [])
+        if sfa_users:
+            slice_record = sfa_users[0].get('slice_record', [])
+
+        # parse rspec
+        rspec = RSpec(rspec_string)
+        # requested_attributes = rspec.version.get_slice_attributes()
+
+        # ensure site record exists
+
+        # ensure slice record exists
+
+        current_slice = slices.verify_slice(xrn.hrn, slice_record, sfa_peer)
+        logger.debug("IOTLABDRIVER.PY \t ===============allocate \t\
+                            \r\n \r\n  current_slice %s" % (current_slice))
+        # ensure person records exists
+
+        # oui c'est degueulasse, le slice_record se retrouve modifie
+        # dans la methode avec les infos du user, els infos sont propagees
+        # dans verify_slice_leases
+        persons = slices.verify_persons(xrn.hrn, slice_record, users,
+                                        options=options)
+        # ensure slice attributes exists
+        # slices.verify_slice_attributes(slice, requested_attributes,
+                                    # options=options)
+
+        # add/remove slice from nodes
+        requested_xp_dict = self._process_requested_xp_dict(rspec)
+
+        logger.debug("IOTLABDRIVER.PY \tallocate  requested_xp_dict %s "
+                     % (requested_xp_dict))
+        request_nodes = rspec.version.get_nodes_with_slivers()
+        nodes_list = []
+        for start_time in requested_xp_dict:
+            lease = requested_xp_dict[start_time]
+            for hostname in lease['hostname']:
+                nodes_list.append(hostname)
+
+        # nodes = slices.verify_slice_nodes(slice_record,request_nodes, peer)
+        logger.debug("IOTLABDRIVER.PY \tallocate  nodes_list %s slice_record %s"
+                     % (nodes_list, slice_record))
+
+        # add/remove leases
+        rspec_requested_leases = rspec.version.get_leases()
+        leases = slices.verify_slice_leases(slice_record,
+                                                requested_xp_dict, peer)
+        logger.debug("IOTLABDRIVER.PY \tallocate leases  %s \
+                        rspec_requested_leases %s" % (leases,
+                        rspec_requested_leases))
+         # update sliver allocations
+        for hostname in nodes_list:
+            client_id = hostname
+            node_urn = xrn_object(self.testbed_shell.root_auth, hostname).urn
+            component_id = node_urn
+            slice_urn = current_slice['reg-urn']
+            for lease in leases:
+                if hostname in lease['reserved_nodes']:
+                    index = lease['reserved_nodes'].index(hostname)
+                    sliver_hrn = '%s.%s-%s' % (self.hrn, lease['lease_id'],
+                                   lease['resource_ids'][index] )
+            sliver_id = Xrn(sliver_hrn, type='sliver').urn
+            record = SliverAllocation(sliver_id=sliver_id, client_id=client_id,
+                                      component_id=component_id,
+                                      slice_urn = slice_urn,
+                                      allocation_state='geni_allocated')
+            record.sync(self.api.dbsession())
+
+        return aggregate.describe([xrn.get_urn()], version=rspec.version)
+
+    def provision(self, urns, options={}):
+        # update users
+        slices = CortexlabSlices(self)
+        aggregate = CortexlabAggregate(self)
+        slivers = aggregate.get_slivers(urns)
+        current_slice = slivers[0]
+        peer = slices.get_peer(current_slice['hrn'])
+        sfa_peer = slices.get_sfa_peer(current_slice['hrn'])
+        users = options.get('geni_users', [])
+        # persons = slices.verify_persons(current_slice['hrn'],
+            # current_slice, users, peer, sfa_peer, options=options)
+        # slices.handle_peer(None, None, persons, peer)
+        # update sliver allocation states and set them to geni_provisioned
+        sliver_ids = [sliver['sliver_id'] for sliver in slivers]
+        dbsession = self.api.dbsession()
+        SliverAllocation.set_allocations(sliver_ids, 'geni_provisioned',
+                                                                dbsession)
+        version_manager = VersionManager()
+        rspec_version = version_manager.get_version(options[
+                                                        'geni_rspec_version'])
+        return self.describe(urns, rspec_version, options=options)
+
+
+
index 54c637a..8c19ed6 100644 (file)
@@ -8,20 +8,13 @@ from datetime import datetime
 
 from sfa.util.sfalogging import logger
 
 
 from sfa.util.sfalogging import logger
 
-from sfa.storage.alchemy import dbsession
-from sqlalchemy.orm import joinedload
-from sfa.storage.model import RegRecord, RegUser, RegSlice, RegKey
 
 
-from sfa.iotlab.iotlabpostgres import TestbedAdditionalSfaDB, LeaseTableXP
+from sfa.iotlab.iotlabpostgres import LeaseTableXP
 from sfa.cortexlab.LDAPapi import LDAPapi
 
 from sfa.cortexlab.LDAPapi import LDAPapi
 
-from sfa.util.xrn import Xrn, hrn_to_urn, get_authority
 
 
-from sfa.trust.certificate import Keypair, convert_public_key
-from sfa.trust.gid import create_uuid
-from sfa.trust.hierarchy import Hierarchy
 
 
-from sfa.iotlab.iotlabaggregate import iotlab_xrn_object
+from sfa.iotlab.iotlabxrn import xrn_object
 from sfa.cortexlab.cortexlabnodes import CortexlabQueryNodes
 
 class CortexlabShell():
 from sfa.cortexlab.cortexlabnodes import CortexlabQueryNodes
 
 class CortexlabShell():
@@ -58,51 +51,6 @@ class CortexlabShell():
         """
         return CortexlabShell._MINIMUM_DURATION
 
         """
         return CortexlabShell._MINIMUM_DURATION
 
-
-    def GetPeers(self, peer_filter=None ):
-        """ Gathers registered authorities in SFA DB and looks for specific peer
-        if peer_filter is specified.
-        :param peer_filter: name of the site authority looked for.
-        :type peer_filter: string
-        :returns: list of records.
-
-        """
-
-        existing_records = {}
-        existing_hrns_by_types = {}
-        logger.debug("CORTEXLAB_API \tGetPeers peer_filter %s " % (peer_filter))
-        all_records = dbsession.query(RegRecord).filter(RegRecord.type.like('%authority%')).all()
-
-        for record in all_records:
-            existing_records[(record.hrn, record.type)] = record
-            if record.type not in existing_hrns_by_types:
-                existing_hrns_by_types[record.type] = [record.hrn]
-            else:
-                existing_hrns_by_types[record.type].append(record.hrn)
-
-        logger.debug("CORTEXLAB_API \tGetPeer\texisting_hrns_by_types %s "
-                     % (existing_hrns_by_types))
-        records_list = []
-
-        try:
-            if peer_filter:
-                records_list.append(existing_records[(peer_filter,
-                                                     'authority')])
-            else:
-                for hrn in existing_hrns_by_types['authority']:
-                    records_list.append(existing_records[(hrn, 'authority')])
-
-            logger.debug("CORTEXLAB_API \tGetPeer \trecords_list  %s "
-                         % (records_list))
-
-        except KeyError:
-            pass
-
-        return_records = records_list
-        logger.debug("CORTEXLAB_API \tGetPeer return_records %s "
-                     % (return_records))
-        return return_records
-
     #TODO  : Handling OR request in make_ldap_filters_from_records
     #instead of the for loop
     #over the records' list
     #TODO  : Handling OR request in make_ldap_filters_from_records
     #instead of the for loop
     #over the records' list
@@ -276,36 +224,7 @@ class CortexlabShell():
         return_node_list = node_list_dict
         return return_node_list
 
         return_node_list = node_list_dict
         return return_node_list
 
-    def AddSlice(self, slice_record, user_record):
-        """
-
-        Add slice to the local cortexlab sfa tables if the slice comes
-            from a federated site and is not yet in the cortexlab sfa DB,
-            although the user has already a LDAP login.
-            Called by verify_slice during lease/sliver creation.
-
-        :param slice_record: record of slice, must contain hrn, gid, slice_id
-            and authority of the slice.
-        :type slice_record: dictionary
-        :param user_record: record of the user
-        :type user_record: RegUser
 
 
-        """
-
-        sfa_record = RegSlice(hrn=slice_record['hrn'],
-                              gid=slice_record['gid'],
-                              pointer=slice_record['slice_id'],
-                              authority=slice_record['authority'])
-        logger.debug("CORTEXLAB_API.PY AddSlice  sfa_record %s user_record %s"
-                     % (sfa_record, user_record))
-        sfa_record.just_created()
-        dbsession.add(sfa_record)
-        dbsession.commit()
-        #Update the reg-researcher dependance table
-        sfa_record.reg_researchers = [user_record]
-        dbsession.commit()
-
-        return
 
 
     def GetSites(self, site_filter_name_list=None, return_fields_list=None):
 
 
     def GetSites(self, site_filter_name_list=None, return_fields_list=None):
@@ -391,85 +310,6 @@ class CortexlabShell():
         return delete_failed or True
 
 
         return delete_failed or True
 
 
-    def __add_person_to_db(self, user_dict):
-        """
-        Add a federated user straight to db when the user issues a lease
-        request with iotlab nodes and that he has not registered with cortexlab
-        yet (that is he does not have a LDAP entry yet).
-        Uses parts of the routines in CortexlabImport when importing user
-        from LDAP.
-        Called by AddPerson, right after LdapAddUser.
-        :param user_dict: Must contain email, hrn and pkey to get a GID
-        and be added to the SFA db.
-        :type user_dict: dict
-
-        """
-        check_if_exists = \
-        dbsession.query(RegUser).filter_by(email = user_dict['email']).first()
-        #user doesn't exists
-        if not check_if_exists:
-            logger.debug("__add_person_to_db \t Adding %s \r\n \r\n \
-                                            " %(user_dict))
-            hrn = user_dict['hrn']
-            person_urn = hrn_to_urn(hrn, 'user')
-            pubkey = user_dict['pkey']
-            try:
-                pkey = convert_public_key(pubkey)
-            except TypeError:
-                #key not good. create another pkey
-                logger.warn('__add_person_to_db: unable to convert public \
-                                    key for %s' %(hrn ))
-                pkey = Keypair(create=True)
-
-
-            if pubkey is not None and pkey is not None :
-                hierarchy = Hierarchy()
-                person_gid = hierarchy.create_gid(person_urn, create_uuid(), \
-                                pkey)
-                if user_dict['email']:
-                    logger.debug("__add_person_to_db \r\n \r\n \
-                        IOTLAB IMPORTER PERSON EMAIL OK email %s "\
-                        %(user_dict['email']))
-                    person_gid.set_email(user_dict['email'])
-
-            user_record = RegUser(hrn=hrn , pointer= '-1', \
-                                    authority=get_authority(hrn), \
-                                    email=user_dict['email'], gid = person_gid)
-            user_record.reg_keys = [RegKey(user_dict['pkey'])]
-            user_record.just_created()
-            dbsession.add (user_record)
-            dbsession.commit()
-        return
-
-
-    def AddPerson(self, record):
-        """
-
-        Adds a new account. Any fields specified in records are used,
-            otherwise defaults are used. Creates an appropriate login by calling
-            LdapAddUser.
-
-        :param record: dictionary with the sfa user's properties.
-        :returns: a dicitonary with the status. If successful, the dictionary
-            boolean is set to True and there is a 'uid' key with the new login
-            added to LDAP, otherwise the bool is set to False and a key
-            'message' is in the dictionary, with the error message.
-        :rtype: dict
-
-        """
-        ret = self.ldap.LdapAddUser(record)
-
-        if ret['bool'] is True:
-            record['hrn'] = self.root_auth + '.' + ret['uid']
-            logger.debug("CORTEXLAB_API AddPerson return code %s record %s  "
-                         % (ret, record))
-            self.__add_person_to_db(record)
-        return ret
-
-
-
-
-
     #TODO AddPersonKey 04/07/2012 SA
     def AddPersonKey(self, person_uid, old_attributes_dict, new_key_dict):
         """Adds a new key to the specified account. Adds the key to the
     #TODO AddPersonKey 04/07/2012 SA
     def AddPersonKey(self, person_uid, old_attributes_dict, new_key_dict):
         """Adds a new key to the specified account. Adds the key to the
@@ -492,6 +332,33 @@ class CortexlabShell():
         logger.warning("CORTEXLAB_API AddPersonKey EMPTY - DO NOTHING \r\n ")
         return ret['bool']
 
         logger.warning("CORTEXLAB_API AddPersonKey EMPTY - DO NOTHING \r\n ")
         return ret['bool']
 
+    def DeleteLeases(self, leases_id_list, slice_hrn):
+        """
+
+        Deletes several leases, based on their experiment ids and the slice
+            they are associated with. Uses DeleteOneLease to delete the
+            experiment on the testbed. Note that one slice can contain multiple
+            experiments, and in this
+            case all the experiments in the leases_id_list MUST belong to this
+            same slice, since there is only one slice hrn provided here.
+
+        :param leases_id_list: list of job ids that belong to the slice whose
+            slice hrn is provided.
+        :param slice_hrn: the slice hrn.
+        :type slice_hrn: string
+
+        .. warning:: Does not have a return value since there was no easy
+            way to handle failure when dealing with multiple job delete. Plus,
+            there was no easy way to report it to the user.
+
+        """
+        logger.debug("CORTEXLAB_API DeleteLeases leases_id_list %s slice_hrn %s \
+                \r\n " %(leases_id_list, slice_hrn))
+        for experiment_id in leases_id_list:
+            self.DeleteOneLease(experiment_id, slice_hrn)
+
+        return
+
 
     @staticmethod
     def _process_walltime(duration):
 
     @staticmethod
     def _process_walltime(duration):
@@ -628,89 +495,7 @@ class CortexlabShell():
         return experiment_id
 
 
         return experiment_id
 
 
-    def AddLeases(self, hostname_list, slice_record,
-                  lease_start_time, lease_duration):
 
 
-        """Creates an experiment on the testbed corresponding to the information
-        provided as parameters. Adds the experiment id and the slice hrn in the
-        lease table on the additional sfa database so that we are able to know
-        which slice has which nodes.
-
-        :param hostname_list: list of nodes' OAR hostnames.
-        :param slice_record: sfa slice record, must contain login and hrn.
-        :param lease_start_time: starting time , unix timestamp format
-        :param lease_duration: duration in minutes
-
-        :type hostname_list: list
-        :type slice_record: dict
-        :type lease_start_time: integer
-        :type lease_duration: integer
-
-        """
-        logger.debug("CORTEXLAB_API \r\n \r\n \t AddLeases hostname_list %s  \
-                slice_record %s lease_start_time %s lease_duration %s  "\
-                 %( hostname_list, slice_record , lease_start_time, \
-                 lease_duration))
-
-        username = slice_record['login']
-
-        experiment_id = self.LaunchExperimentOnTestbed(hostname_list, \
-                                    slice_record['hrn'], \
-                                    lease_start_time, lease_duration, \
-                                    username)
-        start_time = \
-                datetime.fromtimestamp(int(lease_start_time)).\
-                strftime(self.time_format)
-        end_time = lease_start_time + lease_duration
-
-
-        logger.debug("CORTEXLAB_API \r\n \r\n \t AddLeases TURN ON LOGGING SQL \
-                    %s %s %s "%(slice_record['hrn'], experiment_id, end_time))
-
-
-        logger.debug("CORTEXLAB_API \r\n \r\n \t AddLeases %s %s %s " \
-                %(type(slice_record['hrn']), type(experiment_id),
-                type(end_time)))
-
-        testbed_xp_row = LeaseTableXP(slice_hrn=slice_record['hrn'],
-            experiment_id=experiment_id, end_time=end_time)
-
-        logger.debug("CORTEXLAB_API \r\n \r\n \t AddLeases testbed_xp_row %s" \
-                %(testbed_xp_row))
-        self.leases_db.testbed_session.add(testbed_xp_row)
-        self.leases_db.testbed_session.commit()
-
-        logger.debug("CORTEXLAB_API \t AddLeases hostname_list start_time %s " \
-                %(start_time))
-
-        return
-
-    def DeleteLeases(self, leases_id_list, slice_hrn):
-        """
-
-        Deletes several leases, based on their experiment ids and the slice
-            they are associated with. Uses DeleteOneLease to delete the
-            experiment on the testbed. Note that one slice can contain multiple
-            experiments, and in this
-            case all the experiments in the leases_id_list MUST belong to this
-            same slice, since there is only one slice hrn provided here.
-
-        :param leases_id_list: list of job ids that belong to the slice whose
-            slice hrn is provided.
-        :param slice_hrn: the slice hrn.
-        :type slice_hrn: string
-
-        .. warning:: Does not have a return value since there was no easy
-            way to handle failure when dealing with multiple job delete. Plus,
-            there was no easy way to report it to the user.
-
-        """
-        logger.debug("CORTEXLAB_API DeleteLeases leases_id_list %s slice_hrn %s \
-                \r\n " %(leases_id_list, slice_hrn))
-        for experiment_id in leases_id_list:
-            self.DeleteOneLease(experiment_id, slice_hrn)
-
-        return
 
     #Delete the jobs from job_iotlab table
     def DeleteSliceFromNodes(self, slice_record):
 
     #Delete the jobs from job_iotlab table
     def DeleteSliceFromNodes(self, slice_record):
@@ -754,56 +539,73 @@ class CortexlabShell():
         Experiments which last less than 10 min (600 sec) are invalid"""
         return self.grain
 
         Experiments which last less than 10 min (600 sec) are invalid"""
         return self.grain
 
-
-    # @staticmethod
-    # def update_experiments_in_additional_sfa_db( job_oar_list, jobs_psql):
-    #     """ Cleans the iotlab db by deleting expired and cancelled jobs.
-    #     Compares the list of job ids given by OAR with the job ids that
-    #     are already in the database, deletes the jobs that are no longer in
-    #     the OAR job id list.
-    #     :param  job_oar_list: list of job ids coming from OAR
-    #     :type job_oar_list: list
-    #     :param job_psql: list of job ids cfrom the database.
-    #     type job_psql: list
-    #     """
-    #     #Turn the list into a set
-    #     set_jobs_psql = set(jobs_psql)
-
-    #     kept_jobs = set(job_oar_list).intersection(set_jobs_psql)
-    #     logger.debug ( "\r\n \t\ update_experiments_in_additional_sfa_db jobs_psql %s \r\n \t \
-    #         job_oar_list %s kept_jobs %s "%(set_jobs_psql, job_oar_list, kept_jobs))
-    #     deleted_jobs = set_jobs_psql.difference(kept_jobs)
-    #     deleted_jobs = list(deleted_jobs)
-    #     if len(deleted_jobs) > 0:
-    #         self.leases_db.testbed_session.query(LeaseTableXP).filter(LeaseTableXP.job_id.in_(deleted_jobs)).delete(synchronize_session='fetch')
-    #         self.leases_db.testbed_session.commit()
-
-    #     return
-
     @staticmethod
     @staticmethod
-    def filter_lease_name(reservation_list, filter_value):
+    def filter_lease(reservation_list, filter_type, filter_value ):
+        """Filters the lease reservation list by removing each lease whose
+        filter_type is not equal to the filter_value provided. Returns the list
+        of leases in one slice, defined by the slice_hrn if filter_type
+        is 'slice_hrn'. Otherwise, returns all leases scheduled starting from
+        the filter_value if filter_type is 't_from'.
+
+        :param reservation_list: leases list
+        :type reservation_list: list of dictionary
+        :param filter_type: can be either 't_from' or 'slice hrn'
+        :type  filter_type: string
+        :param filter_value: depending on the filter_type, can be the slice_hrn
+            or can be defining a timespan.
+        :type filter_value: if filter_type is 't_from', filter_value is int.
+            if filter_type is 'slice_hrn', filter_value is a string.
+
+
+        :returns: filtered_reservation_list, contains only leases running or
+            scheduled in the given slice (wanted_slice).Dict keys are
+            'lease_id','reserved_nodes','slice_id', 'state', 'user',
+            'component_id_list','slice_hrn', 'resource_ids', 't_from', 't_until'
+        :rtype: list of dict
+
+        """
         filtered_reservation_list = list(reservation_list)
         filtered_reservation_list = list(reservation_list)
-        logger.debug("CORTEXLAB_API \t filter_lease_name reservation_list %s" \
+        logger.debug("IOTLAB_API \t filter_lease_name reservation_list %s" \
                         % (reservation_list))
                         % (reservation_list))
-        for reservation in reservation_list:
-            if 'slice_hrn' in reservation and \
-                reservation['slice_hrn'] != filter_value:
-                filtered_reservation_list.remove(reservation)
+        try:
+            for reservation in reservation_list:
+                if \
+                (filter_type is 'slice_hrn' and \
+                    reservation['slice_hrn'] != filter_value) or \
+                (filter_type is 't_from' and \
+                        reservation['t_from'] > filter_value):
+                    filtered_reservation_list.remove(reservation)
+        except TypeError:
+            logger.log_exc("Iotlabshell filter_lease : filter_type %s \
+                        filter_value %s not in lease" %(filter_type,
+                            filter_value))
 
 
-        logger.debug("CORTEXLAB_API \t filter_lease_name filtered_reservation_list %s" \
-                        % (filtered_reservation_list))
         return filtered_reservation_list
 
         return filtered_reservation_list
 
-    @staticmethod
-    def filter_lease_start_time(reservation_list, filter_value):
-        filtered_reservation_list = list(reservation_list)
+    # @staticmethod
+    # def filter_lease_name(reservation_list, filter_value):
+    #     filtered_reservation_list = list(reservation_list)
+    #     logger.debug("CORTEXLAB_API \t filter_lease_name reservation_list %s" \
+    #                     % (reservation_list))
+    #     for reservation in reservation_list:
+    #         if 'slice_hrn' in reservation and \
+    #             reservation['slice_hrn'] != filter_value:
+    #             filtered_reservation_list.remove(reservation)
+
+    #     logger.debug("CORTEXLAB_API \t filter_lease_name filtered_reservation_list %s" \
+    #                     % (filtered_reservation_list))
+    #     return filtered_reservation_list
+
+    # @staticmethod
+    # def filter_lease_start_time(reservation_list, filter_value):
+    #     filtered_reservation_list = list(reservation_list)
 
 
-        for reservation in reservation_list:
-            if 't_from' in reservation and \
-                reservation['t_from'] > filter_value:
-                filtered_reservation_list.remove(reservation)
+        for reservation in reservation_list:
+            if 't_from' in reservation and \
+                reservation['t_from'] > filter_value:
+                filtered_reservation_list.remove(reservation)
 
 
-        return filtered_reservation_list
+        return filtered_reservation_list
 
     def complete_leases_info(self, unfiltered_reservation_list, db_xp_dict):
 
 
     def complete_leases_info(self, unfiltered_reservation_list, db_xp_dict):
 
@@ -852,99 +654,11 @@ class CortexlabShell():
             #Transform the hostnames into urns (component ids)
             for node in resa['reserved_nodes']:
 
             #Transform the hostnames into urns (component ids)
             for node in resa['reserved_nodes']:
 
-                iotlab_xrn = iotlab_xrn_object(self.root_auth, node)
+                iotlab_xrn = xrn_object(self.root_auth, node)
                 resa['component_id_list'].append(iotlab_xrn.urn)
 
         return local_unfiltered_reservation_list, testbed_xp_list
 
                 resa['component_id_list'].append(iotlab_xrn.urn)
 
         return local_unfiltered_reservation_list, testbed_xp_list
 
-    def GetLeases(self, lease_filter_dict=None, login=None):
-        """
-
-        Get the list of leases from the testbed with complete information
-            about in which slice is running which experiment ans which nodes are
-            involved.
-            Two purposes:
-            -Fetch all the experiments from the testbed (running, waiting..)
-            complete the reservation information with slice hrn
-            found in testbed_xp table. If not available in the table,
-            assume it is a cortexlab slice.
-            -Updates the cortexlab table, deleting jobs when necessary.
-
-        :returns: reservation_list, list of dictionaries with 'lease_id',
-            'reserved_nodes','slice_id','user', 'component_id_list',
-            'slice_hrn', 'resource_ids', 't_from', 't_until'. Other
-            keys can be returned if necessary, such as the 'state' of the lease,
-            if the information has been added in GetReservedNodes.
-        :rtype: list
-
-        """
-
-        unfiltered_reservation_list = self.GetReservedNodes(login)
-
-        reservation_list = []
-        #Find the slice associated with this user ldap uid
-        logger.debug(" CORTEXLAB_API.PY \tGetLeases login %s\
-                        unfiltered_reservation_list %s "
-                     % (login, unfiltered_reservation_list))
-        #Create user dict first to avoid looking several times for
-        #the same user in LDAP SA 27/07/12
-
-
-        db_xp_query = self.leases_db.testbed_session.query(LeaseTableXP).all()
-        db_xp_dict = dict([(row.experiment_id, row.__dict__)
-                               for row in db_xp_query])
-
-        logger.debug("CORTEXLAB_API \tGetLeases db_xp_dict %s"
-                     % (db_xp_dict))
-        db_xp_id_list = [row.experiment_id for row in db_xp_query]
-
-        required_fiels_in_leases = ['lease_id',
-            'reserved_nodes','slice_id',  'user', 'component_id_list',
-            'slice_hrn', 'resource_ids', 't_from', 't_until']
-
-        # Add any missing information on the leases with complete_leases_info
-        unfiltered_reservation_list, testbed_xp_list = \
-            self.complete_leases_info(unfiltered_reservation_list,
-            db_xp_dict)
-        # Check that the list of leases is complete and have the mandatory
-        # information
-        format_status = self.ensure_format_is_valid(unfiltered_reservation_list,
-            required_fiels_in_leases)
-
-        if not format_status:
-            logger.log_exc("\tCortexlabapi \t GetLeases : Missing fields in \
-                reservation list")
-            raise KeyError, "GetLeases : Missing fields in reservation list "
-
-        if lease_filter_dict:
-            logger.debug("CORTEXLAB_API \tGetLeases  \
-                    \r\n leasefilter %s" % ( lease_filter_dict))
-
-            filter_dict_functions = {
-            'slice_hrn' : CortexlabShell.filter_lease_name,
-            't_from' : CortexlabShell.filter_lease_start_time
-            }
-
-            reservation_list = list(unfiltered_reservation_list)
-            for filter_type in lease_filter_dict:
-                logger.debug("CORTEXLAB_API \tGetLeases reservation_list %s" \
-                    % (reservation_list))
-                reservation_list = filter_dict_functions[filter_type](\
-                    reservation_list,lease_filter_dict[filter_type] )
-
-
-        if lease_filter_dict is None:
-            reservation_list = unfiltered_reservation_list
-
-        self.leases_db.update_experiments_in_additional_sfa_db(
-            testbed_xp_list, db_xp_id_list)
-
-        logger.debug(" CORTEXLAB_API.PY \tGetLeases reservation_list %s"
-                     % (reservation_list))
-        return reservation_list
-
-
-
 
 #TODO FUNCTIONS SECTION 04/07/2012 SA
 
 
 #TODO FUNCTIONS SECTION 04/07/2012 SA
 
@@ -1025,36 +739,7 @@ class CortexlabShell():
         #return
 
 
         #return
 
 
-    def GetKeys(self, key_filter=None):
-        """Returns a dict of dict based on the key string. Each dict entry
-        contains the key id, the ssh key, the user's email and the
-        user's hrn.
-        If key_filter is specified and is an array of key identifiers,
-        only keys matching the filter will be returned.
-
-        Admin may query all keys. Non-admins may only query their own keys.
-        FROM PLC API DOC
-
-        :returns: dict with ssh key as key and dicts as value.
-        :rtype: dict
-        """
-        if key_filter is None:
-            keys = dbsession.query(RegKey).options(joinedload('reg_user')).all()
-        else:
-            keys = dbsession.query(RegKey).options(joinedload('reg_user')).filter(RegKey.key.in_(key_filter)).all()
-
-        key_dict = {}
-        for key in keys:
-            key_dict[key.key] = {'key_id': key.key_id, 'key': key.key,
-                                 'email': key.reg_user.email,
-                                 'hrn': key.reg_user.hrn}
-
-        #ldap_rslt = self.ldap.LdapSearch({'enabled']=True})
-        #user_by_email = dict((user[1]['mail'][0], user[1]['sshPublicKey']) \
-                                        #for user in ldap_rslt)
 
 
-        logger.debug("CORTEXLAB_API  GetKeys  -key_dict %s \r\n " % (key_dict))
-        return key_dict
 
     #TODO : test
     def DeleteKey(self, user_record, key_string):
 
     #TODO : test
     def DeleteKey(self, user_record, key_string):
@@ -1079,273 +764,8 @@ class CortexlabShell():
         return ret['bool']
 
 
         return ret['bool']
 
 
-    def _sql_get_slice_info(self, slice_filter):
-        """
-        Get the slice record based on the slice hrn. Fetch the record of the
-        user associated with the slice by using joinedload based on the
-        reg_researcher relationship.
-
-        :param slice_filter: the slice hrn we are looking for
-        :type slice_filter: string
-        :returns: the slice record enhanced with the user's information if the
-            slice was found, None it wasn't.
-
-        :rtype: dict or None.
-        """
-        #DO NOT USE RegSlice - reg_researchers to get the hrn
-        #of the user otherwise will mess up the RegRecord in
-        #Resolve, don't know why - SA 08/08/2012
-
-        #Only one entry for one user  = one slice in testbed_xp table
-        #slicerec = dbsession.query(RegRecord).filter_by(hrn = slice_filter).first()
-        raw_slicerec = dbsession.query(RegSlice).options(joinedload('reg_researchers')).filter_by(hrn=slice_filter).first()
-        #raw_slicerec = dbsession.query(RegRecord).filter_by(hrn = slice_filter).first()
-        if raw_slicerec:
-            #load_reg_researcher
-            #raw_slicerec.reg_researchers
-            raw_slicerec = raw_slicerec.__dict__
-            logger.debug(" CORTEXLAB_API \t  _sql_get_slice_info slice_filter %s  \
-                            raw_slicerec %s" % (slice_filter, raw_slicerec))
-            slicerec = raw_slicerec
-            #only one researcher per slice so take the first one
-            #slicerec['reg_researchers'] = raw_slicerec['reg_researchers']
-            #del slicerec['reg_researchers']['_sa_instance_state']
-            return slicerec
-
-        else:
-            return None
-
-
-    def _sql_get_slice_info_from_user(self, slice_filter):
-        """
-        Get the slice record based on the user recordid by using a joinedload
-        on the relationship reg_slices_as_researcher. Format the sql record
-        into a dict with the mandatory fields for user and slice.
-        :returns: dict with slice record and user record if the record was found
-        based on the user's id, None if not..
-        :rtype:dict or None..
-        """
-        #slicerec = dbsession.query(RegRecord).filter_by(record_id = slice_filter).first()
-        raw_slicerec = dbsession.query(RegUser).options(joinedload('reg_slices_as_researcher')).filter_by(record_id=slice_filter).first()
-        #raw_slicerec = dbsession.query(RegRecord).filter_by(record_id = slice_filter).first()
-        #Put it in correct order
-        user_needed_fields = ['peer_authority', 'hrn', 'last_updated',
-                              'classtype', 'authority', 'gid', 'record_id',
-                              'date_created', 'type', 'email', 'pointer']
-        slice_needed_fields = ['peer_authority', 'hrn', 'last_updated',
-                               'classtype', 'authority', 'gid', 'record_id',
-                               'date_created', 'type', 'pointer']
-        if raw_slicerec:
-            #raw_slicerec.reg_slices_as_researcher
-            raw_slicerec = raw_slicerec.__dict__
-            slicerec = {}
-            slicerec = \
-                dict([(k, raw_slicerec[
-                    'reg_slices_as_researcher'][0].__dict__[k])
-                    for k in slice_needed_fields])
-            slicerec['reg_researchers'] = dict([(k, raw_slicerec[k])
-                                                for k in user_needed_fields])
-             #TODO Handle multiple slices for one user SA 10/12/12
-                        #for now only take the first slice record associated to the rec user
-                        ##slicerec  = raw_slicerec['reg_slices_as_researcher'][0].__dict__
-                        #del raw_slicerec['reg_slices_as_researcher']
-                        #slicerec['reg_researchers'] = raw_slicerec
-                        ##del slicerec['_sa_instance_state']
-
-            return slicerec
-
-        else:
-            return None
-
-    def _get_slice_records(self, slice_filter=None,
-                           slice_filter_type=None):
-        """
-        Get the slice record depending on the slice filter and its type.
-        :param slice_filter: Can be either the slice hrn or the user's record
-        id.
-        :type slice_filter: string
-        :param slice_filter_type: describes the slice filter type used, can be
-        slice_hrn or record_id_user
-        :type: string
-        :returns: the slice record
-        :rtype:dict
-        .. seealso::_sql_get_slice_info_from_user
-        .. seealso:: _sql_get_slice_info
-        """
-
-        #Get list of slices based on the slice hrn
-        if slice_filter_type == 'slice_hrn':
-
-            #if get_authority(slice_filter) == self.root_auth:
-                #login = slice_filter.split(".")[1].split("_")[0]
-
-            slicerec = self._sql_get_slice_info(slice_filter)
 
 
-            if slicerec is None:
-                return None
-                #return login, None
 
 
-        #Get slice based on user id
-        if slice_filter_type == 'record_id_user':
-
-            slicerec = self._sql_get_slice_info_from_user(slice_filter)
-
-        if slicerec:
-            fixed_slicerec_dict = slicerec
-            #At this point if there is no login it means
-            #record_id_user filter has been used for filtering
-            #if login is None :
-                ##If theslice record is from iotlab
-                #if fixed_slicerec_dict['peer_authority'] is None:
-                    #login = fixed_slicerec_dict['hrn'].split(".")[1].split("_")[0]
-            #return login, fixed_slicerec_dict
-            return fixed_slicerec_dict
-        else:
-            return None
-
-
-    def GetSlices(self, slice_filter=None, slice_filter_type=None,
-                  login=None):
-        """Get the slice records from the sfa db and add lease information
-            if any.
-
-        :param slice_filter: can be the slice hrn or slice record id in the db
-            depending on the slice_filter_type.
-        :param slice_filter_type: defines the type of the filtering used, Can be
-            either 'slice_hrn' or 'record_id'.
-        :type slice_filter: string
-        :type slice_filter_type: string
-        :returns: a slice dict if slice_filter  and slice_filter_type
-            are specified and a matching entry is found in the db. The result
-            is put into a list.Or a list of slice dictionnaries if no filters
-            arespecified.
-
-        :rtype: list
-
-        """
-        #login = None
-        authorized_filter_types_list = ['slice_hrn', 'record_id_user']
-        return_slicerec_dictlist = []
-
-        #First try to get information on the slice based on the filter provided
-        if slice_filter_type in authorized_filter_types_list:
-            fixed_slicerec_dict = self._get_slice_records(slice_filter,
-                                                          slice_filter_type)
-            # if the slice was not found in the sfa db
-            if fixed_slicerec_dict is None:
-                return return_slicerec_dictlist
-
-            slice_hrn = fixed_slicerec_dict['hrn']
-
-            logger.debug(" CORTEXLAB_API \tGetSlices login %s \
-                            slice record %s slice_filter %s \
-                            slice_filter_type %s " % (login,
-                            fixed_slicerec_dict, slice_filter,
-                            slice_filter_type))
-
-
-            #Now we have the slice record fixed_slicerec_dict, get the
-            #jobs associated to this slice
-            leases_list = []
-
-            leases_list = self.GetLeases(login=login)
-            #If no job is running or no job scheduled
-            #return only the slice record
-            if leases_list == [] and fixed_slicerec_dict:
-                return_slicerec_dictlist.append(fixed_slicerec_dict)
-
-            # if the jobs running don't belong to the user/slice we are looking
-            # for
-            leases_hrn = [lease['slice_hrn'] for lease in leases_list]
-            if slice_hrn not in leases_hrn:
-                return_slicerec_dictlist.append(fixed_slicerec_dict)
-            #If several experiments for one slice , put the slice record into
-            # each lease information dict
-            for lease in leases_list:
-                slicerec_dict = {}
-                logger.debug("CORTEXLAB_API.PY  \tGetSlices slice_filter %s   \
-                        \t lease['slice_hrn'] %s"
-                             % (slice_filter, lease['slice_hrn']))
-                if lease['slice_hrn'] == slice_hrn:
-                    slicerec_dict['experiment_id'] = lease['lease_id']
-                    #Update lease dict with the slice record
-                    if fixed_slicerec_dict:
-                        fixed_slicerec_dict['experiment_id'] = []
-                        fixed_slicerec_dict['experiment_id'].append(
-                            slicerec_dict['experiment_id'])
-                        slicerec_dict.update(fixed_slicerec_dict)
-
-                    slicerec_dict['slice_hrn'] = lease['slice_hrn']
-                    slicerec_dict['hrn'] = lease['slice_hrn']
-                    slicerec_dict['user'] = lease['user']
-                    slicerec_dict.update(
-                        {'list_node_ids':
-                        {'hostname': lease['reserved_nodes']}})
-                    slicerec_dict.update({'node_ids': lease['reserved_nodes']})
-
-
-                    return_slicerec_dictlist.append(slicerec_dict)
-
-
-                logger.debug("CORTEXLAB_API.PY  \tGetSlices  \
-                        slicerec_dict %s return_slicerec_dictlist %s \
-                        lease['reserved_nodes'] \
-                        %s" % (slicerec_dict, return_slicerec_dictlist,
-                               lease['reserved_nodes']))
-
-            logger.debug("CORTEXLAB_API.PY  \tGetSlices  RETURN \
-                        return_slicerec_dictlist  %s"
-                          % (return_slicerec_dictlist))
-
-            return return_slicerec_dictlist
-
-
-        else:
-            #Get all slices from the cortexlab sfa database , get the user info
-            # as well at the same time put them in dict format
-
-            query_slice_list = \
-                dbsession.query(RegSlice).options(joinedload('reg_researchers')).all()
-
-            for record in query_slice_list:
-                tmp = record.__dict__
-                tmp['reg_researchers'] = tmp['reg_researchers'][0].__dict__
-                return_slicerec_dictlist.append(tmp)
-
-
-            #Get all the experiments reserved nodes
-            leases_list = self.GetReservedNodes()
-
-            for fixed_slicerec_dict in return_slicerec_dictlist:
-                slicerec_dict = {}
-                #Check if the slice belongs to a cortexlab user
-                if fixed_slicerec_dict['peer_authority'] is None:
-                    owner = fixed_slicerec_dict['hrn'].split(
-                        ".")[1].split("_")[0]
-                else:
-                    owner = None
-                for lease in leases_list:
-                    if owner == lease['user']:
-                        slicerec_dict['experiment_id'] = lease['lease_id']
-
-                        #for reserved_node in lease['reserved_nodes']:
-                        logger.debug("CORTEXLAB_API.PY  \tGetSlices lease %s "
-                                     % (lease))
-                        slicerec_dict.update(fixed_slicerec_dict)
-                        slicerec_dict.update({'node_ids':
-                                              lease['reserved_nodes']})
-                        slicerec_dict.update({'list_node_ids':
-                                             {'hostname':
-                                             lease['reserved_nodes']}})
-
-
-                        fixed_slicerec_dict.update(slicerec_dict)
-
-            logger.debug("CORTEXLAB_API.PY  \tGetSlices RETURN \
-                        return_slicerec_dictlist %s \slice_filter %s " \
-                        %(return_slicerec_dictlist, slice_filter))
-
-        return return_slicerec_dictlist