From e67886999832ba3b616c9168f93bcf7d233c5a23 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jordan=20Aug=C3=A9?= Date: Wed, 20 Aug 2014 15:24:30 +0200 Subject: [PATCH] iotlab driver fixed for OneLab in Production --- sfa/iotlab/LDAPapi.py | 14 ++- sfa/iotlab/iotlabaggregate.py | 2 + sfa/iotlab/iotlabdriver.py | 9 +- sfa/iotlab/iotlabslices.py | 176 +++++++++++++++++++++++----------- sfa/trust/hierarchy.py | 4 +- 5 files changed, 140 insertions(+), 65 deletions(-) diff --git a/sfa/iotlab/LDAPapi.py b/sfa/iotlab/LDAPapi.py index 94565b84..217e2001 100644 --- a/sfa/iotlab/LDAPapi.py +++ b/sfa/iotlab/LDAPapi.py @@ -249,6 +249,7 @@ class LoginPassword(): return lower_first_name, lower_last_name + # XXX JORDAN: This function writes an error in the log but returns normally :)) def choose_sets_chars_for_login(self, lower_first_name, lower_last_name): """ @@ -293,6 +294,7 @@ class LoginPassword(): logger.error("LDAP LdapGenerateUniqueLogin failed : \ impossible to generate unique login for %s %s" % (lower_first_name, lower_last_name)) + logger.debug("JORDAN choose_sets_chars_for_login %d %s" % (index, login)) return index, login def generate_password(self): @@ -391,6 +393,7 @@ class LDAPapi: if index >= 9: logger.error("LoginException : Generation login error \ with minimum four characters") + break else: try: login = \ @@ -398,6 +401,7 @@ class LDAPapi: lower_last_name[0: self.login_pwd.login_max_length - index] + logger.debug("JORDAN trying login: %r" % login) login_filter = '(uid=' + login + ')' except KeyError: print "lower_first_name - lower_last_name too short" @@ -459,6 +463,7 @@ class LDAPapi: :rtype: string """ + logger.debug("JORDAN make_ldap_filters_from_record: %r" % record) req_ldap = '' req_ldapdict = {} if record : @@ -514,6 +519,7 @@ class LDAPapi: :rtype: dict """ + logger.debug("JORDAN make_ldap_attributes_from_record: %r" % record) attrs = {} attrs['objectClass'] = ["top", "person", "inetOrgPerson", @@ -570,7 +576,6 @@ class LDAPapi: return attrs - def LdapAddUser(self, record) : """Add SFA user to LDAP if it is not in LDAP yet. @@ -586,10 +591,13 @@ class LDAPapi: """ logger.debug(" \r\n \t LDAP LdapAddUser \r\n\r\n ================\r\n ") user_ldap_attrs = self.make_ldap_attributes_from_record(record) + logger.debug("JORDAN LdapAddUser (ctd) user_ldap_attrs=%r" % user_ldap_attrs) #Check if user already in LDAP wih email, first name and last name filter_by = self.make_ldap_filters_from_record(user_ldap_attrs) + logger.debug("JORDAN LdapAddUser (ctd) filter_by = %r" % filter_by) user_exist = self.LdapSearch(filter_by) + logger.debug("JORDAN LdapAddUser (ctd) user_exist = %r" % user_exist) if user_exist: logger.warning(" \r\n \t LDAP LdapAddUser user %s %s \ already exists" % (user_ldap_attrs['sn'], @@ -598,6 +606,7 @@ class LDAPapi: #Bind to the server result = self.conn.connect() + logger.debug("JORDAN LdapAddUser (ctd) result = %r" % result) if(result['bool']): @@ -830,6 +839,7 @@ class LDAPapi: .. seealso:: make_ldap_filters_from_record for req_ldap format. """ + logger.debug("JORDAN LdapSearch, req_ldap=%r, expected_fields=%r" % (req_ldap, expected_fields)) result = self.conn.connect(bind=False) if (result['bool']): @@ -1018,6 +1028,8 @@ class LDAPapi: :rtype: dict or list """ + logger.debug("JORDAN LdapFindUser record=%r, is_user_enabled=%r, expected_fields=%r" % (record, is_user_enabled, expected_fields)) + custom_record = {} if is_user_enabled: custom_record['enabled'] = is_user_enabled diff --git a/sfa/iotlab/iotlabaggregate.py b/sfa/iotlab/iotlabaggregate.py index e113d8ea..32ad8016 100644 --- a/sfa/iotlab/iotlabaggregate.py +++ b/sfa/iotlab/iotlabaggregate.py @@ -688,8 +688,10 @@ class IotlabAggregate: try: + logger.debug("############################################ iotlab AM : single_slice = %s" % single_slice) node_ids = single_slice['node_ids'] node_list = self.driver.testbed_shell.GetNodes() + logger.debug("############################################ iotlab AM : node_list = %s" % node_list) # JORDAN REMOVED FILTER so that next check always succeed # {'hostname':single_slice['node_ids']}) node_by_hostname = dict([(node['hostname'], node) diff --git a/sfa/iotlab/iotlabdriver.py b/sfa/iotlab/iotlabdriver.py index 1da81c59..855dc350 100644 --- a/sfa/iotlab/iotlabdriver.py +++ b/sfa/iotlab/iotlabdriver.py @@ -153,13 +153,13 @@ class IotlabDriver(Driver): ret = self.testbed_shell.ldap.LdapAddUser(record) if ret['bool'] is True: - record['hrn'] = self.testbed_shell.root_auth + '.' + ret['uid'] + #record['hrn'] = self.testbed_shell.root_auth + '.' + ret['uid'] logger.debug("IOTLAB_API AddPerson return code %s record %s " % (ret, record)) - self.__add_person_to_db(record) + #self.__add_person_to_db(record) return ret - def __add_person_to_db(self, user_dict): + 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 iotlab @@ -191,8 +191,9 @@ class IotlabDriver(Driver): if pubkey is not None and pkey is not None : hierarchy = Hierarchy() + # We fake the parent in order to be able to create a valid GID person_gid = hierarchy.create_gid(person_urn, create_uuid(), \ - pkey) + pkey, force_parent='iotlab') if user_dict['email']: logger.debug("__add_person_to_db \r\n \r\n \ IOTLAB IMPORTER PERSON EMAIL OK email %s "\ diff --git a/sfa/iotlab/iotlabslices.py b/sfa/iotlab/iotlabslices.py index 710f6137..7206c927 100644 --- a/sfa/iotlab/iotlabslices.py +++ b/sfa/iotlab/iotlabslices.py @@ -349,9 +349,12 @@ class IotlabSlices: } 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)) @@ -420,7 +423,7 @@ class IotlabSlices: # % (users_dict, users_by_email)) existing_user_ids = [] - existing_user_emails = [] + existing_users_by_email = dict() existing_users = [] # Check if user is in Iotlab LDAP using its hrn. # Assuming Iotlab is centralised : one LDAP for all sites, @@ -446,8 +449,7 @@ class IotlabSlices: user['login'] = user['uid'] # XXX LOIC Fix we already have all informations comming from Allocate #users_dict[user['email']].update(user) - #existing_user_emails.append( - # users_dict[user['email']]['email']) + existing_users_by_email[user['email']] = user logger.debug("User is in iotlab LDAP slice_record[user] = %s" % slice_user) # User from another known trusted federated site. Check @@ -488,64 +490,122 @@ class IotlabSlices: # 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) - - # XXX JORDAN the uid of the user is put in slice_record['login'] - added_persons = [] - # add new users - #requested_user_email is in existing_user_emails - if len(added_user_emails) == 0: - slice_record['login'] = existing_users[0]['uid'] - #slice_record['login'] = users_dict[requested_user_emails[0]]['uid'] - logger.debug(" IOTLABSLICES \tverify_person QUICK DIRTY %s" - % (slice_record)) - # XXX JORDAN uid == 'register' - - # XXX JORDAN i have no added_user_emails - 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] - # bug user without key - if added_user['keys']: - 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.AddPerson(person) - if 'uid' in ret: - # meaning bool is True and the AddPerson was successful - person['uid'] = ret['uid'] - slice_record['login'] = person['uid'] + # The function returns a list of added persons (to the LDAP ?) + added_persons = list() + + # We go though each requested user and make sure it exists both in the + # LDAP and in the local DB + for user_email in requested_user_emails: + user = users_by_email[user_email] + + person = { + 'peer_person_id': None, + 'mail' : user['email'], + 'email' : user['email'], + 'key_ids' : user.get('key_ids', []), + 'hrn' : users_by_email[user['email']]['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']: + # XXX Only one key is kept for IoTLAB + person['pkey'] = user['keys'][0] + + # LDAP + if users_by_email not in existing_users_by_email.keys(): + ret = self.driver.AddPerson(person) + if 'uid' in ret: + person['uid'] = ret['uid'] + added_persons.append(person) + else: + logger.debug(" IOTLABSLICES ret message %s" %(ret)) else: - # error message in ret - logger.debug(" IOTLABSLICES ret message %s" %(ret)) + person['uid'] = existing_users_by_email[user['email']]['uid'] - logger.debug(" IOTLABSLICES \r\n \r\n \t THE SECOND verify_person\ - person %s" % (person)) - #Update slice_Record with the id now known to LDAP + # Local DB + self.driver.add_person_to_db(person) + + # Set the login in the slice_record XXX + slice_record['login'] = existing_users[0]['uid'] - added_persons.append(person) return added_persons +#DEPRECATED| # users to be added, removed or updated +#DEPRECATED| #One user in one iotlab slice : there should be no need +#DEPRECATED| #to remove/ add any user from/to a slice. +#DEPRECATED| #However a user from SFA which is not registered in Iotlab yet +#DEPRECATED| #should be added to the LDAP. +#DEPRECATED| added_user_emails = set(requested_user_emails).\ +#DEPRECATED| difference(set(existing_user_emails)) +#DEPRECATED| +#DEPRECATED| +#DEPRECATED| #self.verify_keys(existing_slice_users, updated_users_list, \ +#DEPRECATED| #peer, append) +#DEPRECATED| +#DEPRECATED| # XXX JORDAN the uid of the user is put in slice_record['login'] +#DEPRECATED| added_persons = [] +#DEPRECATED| # add new users +#DEPRECATED| #requested_user_email is in existing_user_emails +#DEPRECATED| if len(added_user_emails) == 0: +#DEPRECATED| slice_record['login'] = existing_users[0]['uid'] +#DEPRECATED| #slice_record['login'] = users_dict[requested_user_emails[0]]['uid'] +#DEPRECATED| logger.debug(" IOTLABSLICES \tverify_person QUICK DIRTY %s" +#DEPRECATED| % (slice_record)) +#DEPRECATED| # XXX JORDAN uid == 'register' +#DEPRECATED| logger.debug("JORDAN USERS BY EMAIL: %r" % users_by_email) +#DEPRECATED| +#DEPRECATED| # XXX JORDAN i have no added_user_emails +#DEPRECATED| logger.debug("JORDAN: added_user_emails: %r" % added_user_emails) +#DEPRECATED| for added_user_email in added_user_emails: +#DEPRECATED| added_user = users_dict[added_user_email] +#DEPRECATED| logger.debug(" IOTLABSLICES \r\n \r\n \t verify_person \ +#DEPRECATED| added_user %s" % (added_user)) +#DEPRECATED| person = {} +#DEPRECATED| person['peer_person_id'] = None +#DEPRECATED| k_list = ['first_name', 'last_name', 'person_id'] +#DEPRECATED| for k in k_list: +#DEPRECATED| if k in added_user: +#DEPRECATED| person[k] = added_user[k] +#DEPRECATED| # bug user without key +#DEPRECATED| if added_user['keys']: +#DEPRECATED| person['pkey'] = added_user['keys'][0] +#DEPRECATED| person['mail'] = added_user['email'] +#DEPRECATED| person['email'] = added_user['email'] +#DEPRECATED| person['key_ids'] = added_user.get('key_ids', []) +#DEPRECATED| +#DEPRECATED| # JORDAN +#DEPRECATED| # This is the only call to AddPerson. We need to be sure to provide +#DEPRECATED| # the right hrn, by default it used to be done in the function like +#DEPRECATED| # this: +#DEPRECATED| # person['hrn'] = self.testbed_shell.root_auth + '.' + ret['uid'] +#DEPRECATED| person['hrn'] = users_by_email[added_user['email']]['hrn'] +#DEPRECATED| +#DEPRECATED| # This only deals with the LDAP (now) +#DEPRECATED| ret = self.driver.AddPerson(person) +#DEPRECATED| # This will check if we have a record in the local DB and add it if necessary +#DEPRECATED| self.__add_person_to_db(person) +#DEPRECATED| +#DEPRECATED| if 'uid' in ret: +#DEPRECATED| # meaning bool is True and the AddPerson was successful +#DEPRECATED| person['uid'] = ret['uid'] +#DEPRECATED| slice_record['login'] = person['uid'] +#DEPRECATED| else: +#DEPRECATED| # error message in ret +#DEPRECATED| logger.debug(" IOTLABSLICES ret message %s" %(ret)) +#DEPRECATED| +#DEPRECATED| logger.debug(" IOTLABSLICES \r\n \r\n \t THE SECOND verify_person\ +#DEPRECATED| person %s" % (person)) +#DEPRECATED| #Update slice_Record with the id now known to LDAP +#DEPRECATED| +#DEPRECATED| +#DEPRECATED| added_persons.append(person) +#DEPRECATED| return added_persons + def verify_keys(self, persons, users, peer, options=None): """ diff --git a/sfa/trust/hierarchy.py b/sfa/trust/hierarchy.py index 89b680c8..43b318ee 100644 --- a/sfa/trust/hierarchy.py +++ b/sfa/trust/hierarchy.py @@ -226,11 +226,11 @@ class Hierarchy: # @param uuid the unique identifier to store in the GID # @param pkey the public key to store in the GID - def create_gid(self, xrn, uuid, pkey, CA=False, email=None): + def create_gid(self, xrn, uuid, pkey, CA=False, email=None, force_parent=None): hrn, type = urn_to_hrn(xrn) if not type: type = 'authority' - parent_hrn = get_authority(hrn) + parent_hrn = force_parent if force_parent else get_authority(hrn) # Using hrn_to_urn() here to make sure the urn is in the right format # If xrn was a hrn instead of a urn, then the gid's urn will be # of type None -- 2.43.0