Merge branch 'geni-v3' of ssh://git.onelab.eu/git/sfa into geni-v3
[sfa.git] / sfa / iotlab / iotlabslices.py
index f5ebfa7..e24560c 100644 (file)
@@ -2,7 +2,7 @@
 This file defines the IotlabSlices class by which all the slice checkings
 upon lease creation are done.
 """
 This file defines the IotlabSlices class by which all the slice checkings
 upon lease creation are done.
 """
-from sfa.util.xrn import get_authority, urn_to_hrn
+from sfa.util.xrn import get_authority, urn_to_hrn, hrn_to_urn
 from sfa.util.sfalogging import logger
 
 MAXINT = 2L**31-1
 from sfa.util.sfalogging import logger
 
 MAXINT = 2L**31-1
@@ -133,7 +133,8 @@ class IotlabSlices:
             job['duration'] = \
                 str(int(job['duration']) \
                 * self.driver.testbed_shell.GetLeaseGranularity())
             job['duration'] = \
                 str(int(job['duration']) \
                 * self.driver.testbed_shell.GetLeaseGranularity())
-            if job['duration'] < self.driver.testbed_shell.GetLeaseGranularity():
+            if job['duration'] < \
+                    self.driver.testbed_shell.GetLeaseGranularity():
                 del requested_jobs_dict[job['start_time']]
 
         #Requested jobs
                 del requested_jobs_dict[job['start_time']]
 
         #Requested jobs
@@ -164,6 +165,7 @@ class IotlabSlices:
                          "%( start_time))
             if start_time in current_nodes_reserved_by_start_time:
 
                          "%( start_time))
             if start_time in current_nodes_reserved_by_start_time:
 
+                # JORDAN : if we request the same nodes: do nothing
                 if requested_nodes_by_start_time[start_time] == \
                     current_nodes_reserved_by_start_time[start_time]:
                     continue
                 if requested_nodes_by_start_time[start_time] == \
                     current_nodes_reserved_by_start_time[start_time]:
                     continue
@@ -211,16 +213,20 @@ class IotlabSlices:
                     job['hostname'],
                     sfa_slice, int(job['start_time']),
                     int(job['duration']))
                     job['hostname'],
                     sfa_slice, int(job['start_time']),
                     int(job['duration']))
-                if job_id is not None:
-                    new_leases = self.driver.GetLeases(login=
-                        sfa_slice['login'])
-                    for new_lease in new_leases:
-                        leases.append(new_lease)
+
+                # Removed by jordan
+                #if job_id is not None:
+                #    new_leases = self.driver.GetLeases(login=
+                #        sfa_slice['login'])
+                #    for new_lease in new_leases:
+                #        leases.append(new_lease)
 
         #Deleted leases are the ones with lease id not declared in the Rspec
         if deleted_leases:
             self.driver.testbed_shell.DeleteLeases(deleted_leases,
 
         #Deleted leases are the ones with lease id not declared in the Rspec
         if deleted_leases:
             self.driver.testbed_shell.DeleteLeases(deleted_leases,
-                                                sfa_slice['user']['uid'])
+                                                sfa_slice['login'])
+            #self.driver.testbed_shell.DeleteLeases(deleted_leases,
+            #                                    sfa_slice['user']['uid'])
             logger.debug("IOTLABSLICES \
                           verify_slice_leases slice %s deleted_leases %s"
                          % (sfa_slice, deleted_leases))
             logger.debug("IOTLABSLICES \
                           verify_slice_leases slice %s deleted_leases %s"
                          % (sfa_slice, deleted_leases))
@@ -232,7 +238,10 @@ class IotlabSlices:
                     job['hostname'],
                     sfa_slice, int(job['start_time']),
                     int(job['duration']))
                     job['hostname'],
                     sfa_slice, int(job['start_time']),
                     int(job['duration']))
-        return leases
+
+        # Added by Jordan: until we find a better solution, always update the list of leases
+        return self.driver.GetLeases(login= sfa_slice['login'])
+        #return leases
 
     def verify_slice_nodes(self, sfa_slice, requested_slivers, peer):
         """Check for wanted and unwanted nodes in the slice.
 
     def verify_slice_nodes(self, sfa_slice, requested_slivers, peer):
         """Check for wanted and unwanted nodes in the slice.
@@ -304,20 +313,21 @@ class IotlabSlices:
         """
 
         slicename = slice_hrn
         """
 
         slicename = slice_hrn
-        # check if slice belongs to Iotlab
-        slices_list = self.driver.GetSlices(slice_filter=slicename,
-                                            slice_filter_type='slice_hrn')
-
         sfa_slice = None
 
         sfa_slice = None
 
-        if slices_list:
-            for sl in slices_list:
-
-                logger.debug("SLABSLICE \t verify_slice slicename %s \
-                                slices_list %s sl %s \r slice_record %s"
-                             % (slicename, slices_list, sl, slice_record))
-                sfa_slice = sl
-                sfa_slice.update(slice_record)
+        # check if slice belongs to Iotlab
+        if slicename.startswith("iotlab"):
+            slices_list = self.driver.GetSlices(slice_filter=slicename,
+                                                slice_filter_type='slice_hrn')
+    
+            if slices_list:
+                for sl in slices_list:
+    
+                    logger.debug("IOTLABSLICES \t verify_slice slicename %s \
+                                    slices_list %s sl %s \r slice_record %s"
+                                 % (slicename, slices_list, sl, slice_record))
+                    sfa_slice = sl
+                    sfa_slice.update(slice_record)
 
         else:
             #Search for user in ldap based on email SA 14/11/12
 
         else:
             #Search for user in ldap based on email SA 14/11/12
@@ -332,19 +342,24 @@ class IotlabSlices:
                          'node_list': [],
                          'authority': slice_record['authority'],
                          'gid': slice_record['gid'],
                          'node_list': [],
                          'authority': slice_record['authority'],
                          'gid': slice_record['gid'],
-                         'slice_id': slice_record['record_id'],
+                         #'slice_id': slice_record['record_id'],
                          'reg-researchers': slice_record['reg-researchers'],
                          'reg-researchers': slice_record['reg-researchers'],
-                         'peer_authority': str(sfa_peer)
+                         'urn': hrn_to_urn(slicename,'slice'),
+                         #'peer_authority': str(sfa_peer)
                          }
 
             if ldap_user:
                          }
 
             if ldap_user:
-                hrn = self.driver.testbed_shell.root_auth + '.' + ldap_user['uid']
-                user = self.driver.get_user_record(hrn)
+#                hrn = self.driver.testbed_shell.root_auth + '.' \
+#                                                + ldap_user['uid']
+                for hrn in slice_record['reg-researchers']:
+                    user = self.driver.get_user_record(hrn)
+                    if user:
+                        break
 
                 logger.debug(" IOTLABSLICES \tverify_slice hrn %s USER %s"
                              % (hrn, user))
 
 
                 logger.debug(" IOTLABSLICES \tverify_slice hrn %s USER %s"
                              % (hrn, user))
 
-                 # add the external slice to the local SFA iotlab DB
+                # add the external slice to the local SFA iotlab DB
                 if sfa_slice:
                     self.driver.AddSlice(sfa_slice, user)
 
                 if sfa_slice:
                     self.driver.AddSlice(sfa_slice, user)
 
@@ -352,9 +367,9 @@ class IotlabSlices:
         return sfa_slice
 
 
         return sfa_slice
 
 
-    def verify_persons(self, slice_hrn, slice_record, users, options={}):
+    def verify_persons(self, slice_hrn, slice_record, users, options=None):
         """Ensures the users in users list exist and are enabled in LDAP. Adds
         """Ensures the users in users list exist and are enabled in LDAP. Adds
-        person if needed.
+        person if needed (AddPerson).
 
         Checking that a user exist is based on the user's email. If the user is
         still not found in the LDAP, it means that the user comes from another
 
         Checking that a user exist is based on the user's email. If the user is
         still not found in the LDAP, it means that the user comes from another
@@ -366,8 +381,8 @@ class IotlabSlices:
         :param slice_record: record of the slice_hrn
         :param users: users is a record list. Records can either be
             local records or users records from known and trusted federated
         :param slice_record: record of the slice_hrn
         :param users: users is a record list. Records can either be
             local records or users records from known and trusted federated
-            sites.If the user is from another site that iotlab doesn't trust yet,
-            then Resolve will raise an error before getting to create_sliver.
+            sites.If the user is from another site that iotlab doesn't trust
+            yet, then Resolve will raise an error before getting to allocate.
 
         :type slice_hrn: string
         :type slice_record: string
 
         :type slice_hrn: string
         :type slice_record: string
@@ -375,159 +390,42 @@ class IotlabSlices:
 
         .. seealso:: AddPerson
         .. note:: Removed unused peer and sfa_peer parameters. SA 18/07/13.
 
         .. seealso:: AddPerson
         .. note:: Removed unused peer and sfa_peer parameters. SA 18/07/13.
-
-
         """
         """
-        #TODO SA 21/08/12 verify_persons Needs review
-
-        logger.debug("IOTLABSLICES \tverify_persons \tslice_hrn  %s  \
-                    \t slice_record %s\r\n users %s \t  "
-                     % (slice_hrn, slice_record, users))
-
-        users_by_email = {}
-        #users_dict : dict whose keys can either be the user's hrn or its id.
-        #Values contains only id and hrn
-        users_dict = {}
-
-        #First create dicts by hrn and id for each user in the user record list:
-        for info in users:
-            # if 'slice_record' in info:
-            #     slice_rec = info['slice_record']
-                # if 'user' in slice_rec :
-                #     user = slice_rec['user']
-
-            if 'email' in info:
-                users_by_email[info['email']] = info
-                users_dict[info['email']] = info
-
-        logger.debug("SLABSLICE.PY \t verify_person  \
-                        users_dict %s \r\n user_by_email %s \r\n  "
-                     % (users_dict, users_by_email))
-
-        existing_user_ids = []
-        existing_user_emails = []
-        existing_users = []
-        # Check if user is in Iotlab LDAP using its hrn.
-        # Assuming Iotlab is centralised :  one LDAP for all sites,
-        # user's record_id unknown from LDAP
-        # LDAP does not provide users id, therefore we rely on email to find the
-        # user in LDAP
-
-        if users_by_email:
-            #Construct the list of filters (list of dicts) for GetPersons
-            filter_user = [users_by_email[email] for email in users_by_email]
-            #Check user i in LDAP with GetPersons
-            #Needed because what if the user has been deleted in LDAP but
-            #is still in SFA?
-            existing_users = self.driver.testbed_shell.GetPersons(filter_user)
-            logger.debug(" \r\n IOTLABSLICES.PY \tverify_person  filter_user %s\
-                       existing_users %s  "
-                        % (filter_user, existing_users))
-            #User is in iotlab LDAP
-            if existing_users:
-                for user in existing_users:
-                    user['login'] = user['uid']
-                    users_dict[user['email']].update(user)
-                    existing_user_emails.append(
-                        users_dict[user['email']]['email'])
-
-
-            # User from another known trusted federated site. Check
-            # if a iotlab account matching the email has already been created.
-            else:
-                req = 'mail='
-                if isinstance(users, list):
-                    req += users[0]['email']
-                else:
-                    req += users['email']
-                ldap_reslt = self.driver.testbed_shell.ldap.LdapSearch(req)
-
-                if ldap_reslt:
-                    logger.debug(" SLABSLICE.PY \tverify_person users \
-                                USER already in Iotlab \t ldap_reslt %s \
-                                " % (ldap_reslt))
-                    existing_users.append(ldap_reslt[1])
-
-                else:
-                    #User not existing in LDAP
-                    logger.debug("SLABSLICE.PY \tverify_person users \
-                                not in ldap ...NEW ACCOUNT NEEDED %s \r\n \t \
-                                ldap_reslt %s " % (users, ldap_reslt))
-
-        requested_user_emails = users_by_email.keys()
-        requested_user_hrns = \
-            [users_by_email[user]['hrn'] for user in users_by_email]
-        logger.debug("SLABSLICE.PY \tverify_person  \
-                       users_by_email  %s " % (users_by_email))
-
-        #Check that the user of the slice in the slice record
-        #matches one of the existing users
-        try:
-            if slice_record['reg-researchers'][0] in requested_user_hrns:
-                logger.debug(" SLABSLICE  \tverify_person ['PI']\
-                                slice_record %s" % (slice_record))
-
-        except KeyError:
-            pass
-
-        # users to be added, removed or updated
-        #One user in one iotlab slice : there should be no need
-        #to remove/ add any user from/to a slice.
-        #However a user from SFA which is not registered in Iotlab yet
-        #should be added to the LDAP.
-        added_user_emails = set(requested_user_emails).\
-                                        difference(set(existing_user_emails))
-
-
-        #self.verify_keys(existing_slice_users, updated_users_list, \
-                                                            #peer, append)
-
-        added_persons = []
-        # add new users
-        #requested_user_email is in existing_user_emails
-        if len(added_user_emails) == 0:
-            slice_record['login'] = users_dict[requested_user_emails[0]]['uid']
-            logger.debug(" SLABSLICE  \tverify_person QUICK DIRTY %s"
-                         % (slice_record))
-
-        for added_user_email in added_user_emails:
-            added_user = users_dict[added_user_email]
-            logger.debug(" IOTLABSLICES \r\n \r\n  \t  verify_person \
-                         added_user %s" % (added_user))
-            person = {}
-            person['peer_person_id'] = None
-            k_list = ['first_name', 'last_name', 'person_id']
-            for k in k_list:
-                if k in added_user:
-                    person[k] = added_user[k]
-
-            person['pkey'] = added_user['keys'][0]
-            person['mail'] = added_user['email']
-            person['email'] = added_user['email']
-            person['key_ids'] = added_user.get('key_ids', [])
-
-            ret = self.driver.testbed_shell.AddPerson(person)
-            if 'uid' in ret:
-                # meaning bool is True and the AddPerson was successful
-                person['uid'] = ret['uid']
-                slice_record['login'] = person['uid']
-            else:
-                # error message in ret
-                logger.debug(" IOTLABSLICES ret message %s" %(ret))
-
-            logger.debug(" SLABSLICE \r\n \r\n  \t THE SECOND verify_person\
-                           person %s" % (person))
-            #Update slice_Record with the id now known to LDAP
-
-
-            added_persons.append(person)
-        return added_persons
-
-
-    def verify_keys(self, persons, users, peer, options={}):
+        if options is None: options={}
+        user = slice_record['user']
+        logger.debug("IOTLABSLICES \tverify_persons \tuser  %s " % user)
+        person = {
+                'peer_person_id': None,
+                'mail'      : user['email'],
+                'email'     : user['email'],
+                'key_ids'   : user.get('key_ids', []),
+                'hrn'       : user['hrn'],
+        }
+        if 'first_name' in user:
+            person['first_name'] = user['first_name']
+        if 'last_name' in user:
+            person['last_name'] = user['last_name']
+        if 'person_id' in user:
+            person['person_id'] = user['person_id']
+        if user['keys']:
+            # Only one key is kept for IoTLAB
+            person['pkey'] = user['keys'][0]
+        # SFA DB (if user already exist we do nothing)
+        self.driver.add_person_to_db(person)
+        # Iot-LAB LDAP (if user already exist we do nothing)
+        ret = self.driver.AddPerson(person)
+        # user uid information is only in LDAP
+        # Be carreful : global scope of dict slice_record in driver
+        slice_record['login'] = ret['uid']
+        return person
+
+       
+
+    def verify_keys(self, persons, users, peer, options=None):
         """
         .. warning:: unused
         """
         """
         .. warning:: unused
         """
+        if options is None: options={}
         # existing keys
         key_ids = []
         for person in persons:
         # existing keys
         key_ids = []
         for person in persons:
@@ -570,12 +468,6 @@ class IotlabSlices:
                                             #key['key_id'], peer['shortname'], \
                                             #remote_key_id)
 
                                             #key['key_id'], peer['shortname'], \
                                             #remote_key_id)
 
-                    #finally:
-                        #if peer:
-                            #self.driver.testbed_shell.BindObjectToPeer('person', \
-                                    #person['person_id'], peer['shortname'], \
-                                    #user['person_id'])
-
         # remove old keys (only if we are not appending)
         append = options.get('append', True)
         if append is False:
         # remove old keys (only if we are not appending)
         append = options.get('append', True)
         if append is False: