X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fplc%2Fapi.py;h=5af31ec23bc9497d06c5d988161ca6989bcfb399;hb=c3c6bd1c3ce8cb5f242bd175cc84608a0a7f8015;hp=fefb5bf37ac04fe6919f2cf7024883061ace5603;hpb=6691cc4c8f8ca1b6ed0a634c44627e8248db81b9;p=sfa.git diff --git a/sfa/plc/api.py b/sfa/plc/api.py index fefb5bf3..5af31ec2 100644 --- a/sfa/plc/api.py +++ b/sfa/plc/api.py @@ -17,7 +17,10 @@ from sfa.util.faults import * from sfa.util.debug import * from sfa.trust.rights import * from sfa.trust.credential import * +from sfa.trust.certificate import * from sfa.util.misc import * +from sfa.util.sfalogging import * +from sfa.util.genitable import * # See "2.2 Characters" in the XML specification: # @@ -113,29 +116,35 @@ class GeniAPI: self.auth = Auth(peer_cert) self.interface = interface self.key_file = key_file + self.key = Keypair(filename=self.key_file) self.cert_file = cert_file + self.cert = Certificate(filename=self.cert_file) self.credential = None - self.plshell = self.getPLCShell() - self.plshell_version = self.getPLCShellVersion() - self.basedir = self.config.SFA_BASE_DIR + os.sep - self.server_basedir = self.basedir + os.sep + "geni" + os.sep + + # Initialize the PLC shell only if SFA wraps a myPLC + rspec_type = self.config.get_aggregate_rspec_type() + if (rspec_type == 'pl' or rspec_type == 'vini'): + self.plshell = self.getPLCShell() + self.plshell_version = self.getPLCShellVersion() + self.hrn = self.config.SFA_INTERFACE_HRN self.time_format = "%Y-%m-%d %H:%M:%S" - + self.logger=get_sfa_logger() def getPLCShell(self): self.plauth = {'Username': self.config.SFA_PLC_USER, 'AuthMethod': 'password', 'AuthString': self.config.SFA_PLC_PASSWORD} try: + self.plshell_type = 'direct' import PLC.Shell shell = PLC.Shell.Shell(globals = globals()) shell.AuthCheck(self.plauth) return shell except ImportError: + self.plshell_type = 'xmlrpc' # connect via xmlrpc url = self.config.SFA_PLC_URL - shell = xmlrpclib.Server(url, verbose = 0, allow_none = True) shell.AuthCheck(self.plauth) return shell @@ -161,25 +170,33 @@ class GeniAPI: else: return self.getCredentialFromRegistry() - def getCredentialFromRegistry(self): """ Get our credential from a remote registry using a geniclient connection """ type = 'authority' - path = self.config.config_path + path = self.config.SFA_BASE_DIR filename = ".".join([self.interface, self.hrn, type, "cred"]) cred_filename = path + os.sep + filename try: credential = Credential(filename = cred_filename) - return credential + return credential.save_to_string(save_parents=True) except IOError: from sfa.server.registry import Registries registries = Registries(self) registry = registries[self.hrn] - self_cred = registry.get_credential(None, type, self.hrn) - cred = registry.get_credential(self_cred, type, self.hrn) - cred.save_to_file(cred_filename, save_parents=True) + cert_string=self.cert.save_to_string(save_parents=True) + # get self credential + arg_list = [cert_string,type,self.hrn] + request_hash=self.key.compute_hash(arg_list) + self_cred = registry.get_self_credential(cert_string, type, self.hrn, request_hash) + # get credential + arg_list = [self_cred,type,self.hrn] + request_hash=self.key.compute_hash(arg_list) + cred = registry.get_credential(self_cred, type, self.hrn, request_hash) + + # save cred to file + Credential(string=cred).save_to_file(cred_filename, save_parents=True) return cred def getCredentialFromLocalRegistry(self): @@ -189,15 +206,17 @@ class GeniAPI: hrn = self.hrn auth_hrn = self.auth.get_authority(hrn) - if not auth_hrn: + + # is this a root or sub authority + if not auth_hrn or hrn == self.config.SFA_INTERFACE_HRN: auth_hrn = hrn auth_info = self.auth.get_auth_info(auth_hrn) - table = self.auth.get_auth_table(auth_hrn) - records = table.resolve('*', hrn) + table = GeniTable() + records = table.findObjects(hrn) if not records: raise RecordNotFound record = records[0] - type = record.get_type() + type = record['type'] object_gid = record.get_gid_object() new_cred = Credential(subject = object_gid.get_subject()) new_cred.set_gid_caller(object_gid) @@ -214,7 +233,7 @@ class GeniAPI: new_cred.encode() new_cred.sign() - return new_cred + return new_cred.save_to_string(save_parents=True) def loadCredential (self): @@ -226,7 +245,7 @@ class GeniAPI: # see if this file exists # XX This is really the aggregate's credential. Using this is easier than getting # the registry's credential from iteslf (ssl errors). - ma_cred_filename = self.server_basedir + os.sep + self.interface + self.hrn + ".ma.cred" + ma_cred_filename = self.config.SFA_BASE_DIR + os.sep + self.interface + self.hrn + ".ma.cred" try: self.credential = Credential(filename = ma_cred_filename) except IOError: @@ -263,9 +282,9 @@ class GeniAPI: elif type == "node": if not "hostname" in pl_record: - if not "dns" in record: - raise MissingGeniInfo("dns") - pl_record["hostname"] = record["dns"] + if not "hostname" in record: + raise MissingGeniInfo("hostname") + pl_record["hostname"] = record["hostname"] if not "model" in pl_record: pl_record["model"] = "geni" @@ -296,8 +315,8 @@ class GeniAPI: @param record: record to fill in field (in/out param) """ - type = record.get_type() - pointer = record.get_pointer() + type = record['type'] + pointer = record['pointer'] auth_hrn = self.hrn login_base = '' # records with pointer==-1 do not have plc info associated with them. @@ -307,7 +326,7 @@ class GeniAPI: record.update({}) return - if (type in ["authority", "sa", "ma"]): + if (type in ["authority"]): pl_res = self.plshell.GetSites(self.plauth, [pointer]) elif (type == "slice"): pl_res = self.plshell.GetSlices(self.plauth, [pointer]) @@ -319,7 +338,7 @@ class GeniAPI: raise UnknownGeniType(type) if not pl_res: - raise PlanetLabRecordDoesNotExist(record.get_name()) + raise PlanetLabRecordDoesNotExist(record['hrn']) # convert ids to hrns pl_record = pl_res[0] @@ -359,35 +378,42 @@ class GeniAPI: record.update(pl_record) - def lookup_users(self, auth_table, user_id_list, role="*"): - record_list = [] - for person_id in user_id_list: - user_records = auth_table.find("user", person_id, "pointer") - for user_record in user_records: - self.fill_record_info(user_record) - user_roles = user_record.get("roles") - if (role=="*") or (role in user_roles): - record_list.append(user_record.get_name()) - return record_list def fill_record_geni_info(self, record): geni_info = {} - type = record.get_type() + type = record['type'] + table = GeniTable() if (type == "slice"): - auth_table = self.auth.get_auth_table(self.auth.get_authority(record.get_name())) person_ids = record.get("person_ids", []) - researchers = self.lookup_users(auth_table, person_ids) + persons = table.find({'type': 'user', 'pointer': person_ids}) + researchers = [person['hrn'] for person in persons] geni_info['researcher'] = researchers elif (type == "authority"): - auth_table = self.auth.get_auth_table(record.get_name()) person_ids = record.get("person_ids", []) - pis = self.lookup_users(auth_table, person_ids, "pi") - operators = self.lookup_users(auth_table, person_ids, "tech") - owners = self.lookup_users(auth_table, person_ids, "admin") - geni_info['pi'] = pis - geni_info['operator'] = operators - geni_info['owner'] = owners + persons = table.find({'type': 'user', 'pointer': person_ids}) + persons_dict = {} + for person in persons: + persons_dict[person['pointer']] = person + pl_persons = self.plshell.GetPersons(self.plauth, person_ids, ['person_id', 'roles']) + pis, techs, admins = [], [], [] + for person in pl_persons: + pointer = person['person_id'] + + if pointer not in persons_dict: + # this means there is not sfa record for this user + continue + hrn = persons_dict[pointer]['hrn'] + if 'pi' in person['roles']: + pis.append(hrn) + if 'tech' in person['roles']: + techs.append(hrn) + if 'admin' in person['roles']: + admins.append(hrn) + + geni_info['PI'] = pis + geni_info['operator'] = techs + geni_info['owner'] = admins # xxx TODO: OrganizationName elif (type == "node"): @@ -423,16 +449,10 @@ class GeniAPI: # build a list of the new person ids, by looking up each person to get # their pointer newIdList = [] - for hrn in newList: - auth_hrn = self.auth.get_authority(hrn) - if not auth_hrn: - auth_hrn = hrn - auth_info = self.auth.get_auth_info(auth_hrn) - table = self.auth.get_auth_table(auth_hrn) - records = table.resolve('user', hrn) - if records: - userRecord = records[0] - newIdList.append(userRecord.get_pointer()) + table = GeniTable() + records = table.find({'type': 'user', 'hrn': newList}) + for rec in records: + newIdList.append(rec['pointer']) # build a list of the old person ids from the person_ids field if oldRecord: @@ -447,13 +467,11 @@ class GeniAPI: # add people who are in the new list, but not the oldList for personId in newIdList: if not (personId in oldIdList): - print "adding id", personId, "to", record.get_name() addFunc(self.plauth, personId, containerId) # remove people who are in the old list, but not the new list for personId in oldIdList: if not (personId in newIdList): - print "removing id", personId, "from", record.get_name() delFunc(self.plauth, personId, containerId) def update_membership(self, oldRecord, record): @@ -497,7 +515,6 @@ class GeniAPI: """ Handle an XML-RPC or SOAP request from the specified source. """ - # Parse request into method name and arguments try: interface = xmlrpclib @@ -537,3 +554,4 @@ class GeniAPI: data = buildSOAP(kw = {'%sResponse' % method: {'Result': result}}, encoding = self.encoding) return data +