class RedeemTicket(Method): """ @param cred credential string specifying the rights of the caller @param ticket @return 1 is successful, faults otherwise """ interfaces = ['component'] accepts = [ Parameter(str, "Ticket string representation of SFA ticket"), Mixed(Parameter(str, "Credential string"), Parameter(type([str]), "List of credentials")), ] returns = [Parameter(int, "1 if successful")] def call(self, ticket, creds): valid_creds = self.api.auth.checkCredentials(cred, 'redeemticket') self.api.auth.check_ticket(ticket) # send the call to the right manager self.api.manager.redeem_ticket(self.api, ticket) return 1
class UpdateSliver(CreateSliver): """ Allocate resources to a slice. This operation is expected to start the allocated resources asynchornously after the operation has successfully completed. Callers can check on the status of the resources using SliverStatus. @param slice_urn (string) URN of slice to allocate to @param credentials ([string]) of credentials @param rspec (string) rspec to allocate """ interfaces = ['aggregate', 'slicemgr'] accepts = [ Parameter(str, "Slice URN"), Mixed(Parameter(str, "Credential string"), Parameter(type([str]), "List of credentials")), Parameter(str, "RSpec"), Parameter(type([]), "List of user information"), Parameter(dict, "options"), ] returns = Parameter(str, "Allocated RSpec") def call(self, slice_xrn, creds, rspec, users, options): return CreateSliver.call(self, slice_xrn, creds, rspec, users, options)
class ListSlices(Method): """ List the slices instantiated at this interface @param cred credential string specifying the rights of the caller @return 1 is successful, faults otherwise """ interfaces = ['aggregate', 'slicemgr', 'component'] accepts = [ Mixed(Parameter(str, "Credential string"), Parameter(type([str]), "List of credentials")), Parameter(dict, "options"), ] returns = Parameter(list, "List of slice names") def call(self, creds, options): valid_creds = self.api.auth.checkCredentials(creds, 'listslices') #log the call origin_hrn = Credential( string=valid_creds[0]).get_gid_caller().get_hrn() self.api.logger.info("interface: %s\tcaller-hrn: %s\tmethod-name: %s" % (self.api.interface, origin_hrn, self.name)) return self.api.manager.ListSlices(self.api, creds, options)
class reset_slice(Method): """ Reset the specified slice @param cred credential string specifying the rights of the caller @param xrn human readable name of slice to instantiate (hrn or urn) @return 1 is successful, faults otherwise """ interfaces = ['aggregate', 'slicemgr', 'component'] accepts = [ Parameter(str, "Credential string"), Parameter(str, "Human readable name of slice to instantiate (hrn or urn)"), Mixed(Parameter(str, "Human readable name of the original caller"), Parameter(None, "Origin hrn not specified")) ] returns = Parameter(int, "1 if successful") def call(self, cred, xrn, origin_hrn=None): hrn, type = urn_to_hrn(xrn) self.api.auth.check(cred, 'resetslice', hrn) self.api.manager.reset_slice(self.api, xrn) return 1
class List(Method): """ List the records in an authority. @param cred credential string specifying the rights of the caller @param hrn human readable name of authority to list (hrn or urn) @return list of record dictionaries """ interfaces = ['registry'] accepts = [ Parameter(str, "Human readable name (hrn or urn)"), Mixed(Parameter(str, "Credential string"), Parameter(type([str]), "List of credentials")), ] # xxx used to be [SfaRecord] returns = [Parameter(dict, "registry record")] def call(self, xrn, creds, options={}): hrn, type = urn_to_hrn(xrn) valid_creds = self.api.auth.checkCredentials(creds, 'list') #log the call origin_hrn = Credential( string=valid_creds[0]).get_gid_caller().get_hrn() self.api.logger.info( "interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s" % (self.api.interface, origin_hrn, hrn, self.name)) return self.api.manager.List(self.api, xrn, options=options)
class get_trusted_certs(Method): """ @param cred credential string specifying the rights of the caller @return list of gid strings """ interfaces = ['registry', 'aggregate', 'slicemgr'] accepts = [ Mixed(Parameter(str, "Credential string"), Parameter(None, "Credential not specified")) ] returns = Parameter(type([str]), "List of GID strings") def call(self, cred=None): # If cred is not specified just return the gid for this interface. # This is true when when a peer is attempting to initiate federation # with this interface self.api.logger.debug("get_trusted_certs: %r" % cred) if not cred: gid_strings = [] for gid in self.api.auth.trusted_cert_list: if gid.get_hrn() == self.api.config.SFA_INTERFACE_HRN: gid_strings.append(gid.save_to_string(save_parents=True)) return gid_strings # authenticate the cred self.api.auth.check(cred, 'gettrustedcerts') gid_strings = [gid.save_to_string(save_parents=True) for \ gid in self.api.auth.trusted_cert_list] return gid_strings
class Resolve(Method): """ Resolve a record. @param cred credential string authorizing the caller @param hrn human readable name to resolve (hrn or urn) @return a list of record dictionaries or empty list """ interfaces = ['registry'] # should we not accept an optional 'details' argument ? accepts = [ Mixed(Parameter(str, "Human readable name (hrn or urn)"), Parameter(list, "List of Human readable names ([hrn])")), Mixed(Parameter(str, "Credential string"), Parameter(list, "List of credentials)")), Parameter(dict, "options"), ] # xxx used to be [SfaRecord] returns = [Parameter(dict, "registry record")] def call(self, xrns, creds, options={}): # use details=False by default, only when explicitly specified do we want # to mess with the testbed details if 'details' in options: details = options['details'] else: details = False type = None if not isinstance(xrns, types.ListType): type = Xrn(xrns).get_type() xrns = [xrns] hrns = [urn_to_hrn(xrn)[0] for xrn in xrns] #find valid credentials valid_creds = self.api.auth.checkCredentials(creds, 'resolve') #log the call origin_hrn = Credential( string=valid_creds[0]).get_gid_caller().get_hrn() self.api.logger.info( "interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s" % (self.api.interface, origin_hrn, hrns, self.name)) # send the call to the right manager return self.api.manager.Resolve(self.api, xrns, type, details=details)
class GetCredential(Method): """ Retrive a credential for an object If cred == None then the behavior reverts to GetSelfCredential @param hrn human readable name of object (hrn or urn) @param cred credential object specifying rights of the caller @param type type of object (user | slice | node | authority ) @return the string representation of a credential object """ interfaces = ['registry'] accepts = [ Mixed(Parameter(str, "Credential string"), Parameter(type([str]), "List of credentials")), Parameter(str, "Human readable name (hrn or urn)"), Mixed(Parameter(str, "Record type"), Parameter(None, "Type not specified")), ] returns = Parameter(str, "String representation of a credential object") def call(self, creds, xrn, type): if type: hrn = urn_to_hrn(xrn)[0] else: hrn, type = urn_to_hrn(xrn) # check creds valid_creds = self.api.auth.checkCredentials(creds, 'getcredential') self.api.auth.verify_object_belongs_to_me(hrn) #log the call origin_hrn = Credential( string=valid_creds[0]).get_gid_caller().get_hrn() self.api.logger.info( "interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s" % (self.api.interface, origin_hrn, hrn, self.name)) return self.api.manager.GetCredential( self.api, xrn, type, self.api.auth.client_gid.get_urn())
class Remove(Method): """ Remove an object from the registry. If the object represents a PLC object, then the PLC records will also be removed. @param cred credential string @param type record type @param xrn human readable name of record to remove (hrn or urn) @return 1 if successful, faults otherwise """ interfaces = ['registry'] accepts = [ Parameter(str, "Human readable name of slice to instantiate (hrn or urn)"), Mixed(Parameter(str, "Credential string"), Parameter(type([str]), "List of credentials")), Mixed(Parameter(str, "Record type"), Parameter(None, "Type not specified")), ] returns = Parameter(int, "1 if successful") def call(self, xrn, creds, type): xrn = Xrn(xrn, type=type) # validate the cred valid_creds = self.api.auth.checkCredentials(creds, "remove") self.api.auth.verify_object_permission(xrn.get_hrn()) #log the call origin_hrn = Credential( string=valid_creds[0]).get_gid_caller().get_hrn() self.api.logger.info( "interface: %s\tmethod-name: %s\tcaller-hrn: %s\ttarget-urn: %s" % (self.api.interface, self.name, origin_hrn, xrn.get_urn())) return self.api.manager.Remove(self.api, xrn)
class GetGids(Method): """ Get a list of record information (hrn, gid and type) for the specified hrns. @param cred credential string @param cert certificate string @return """ interfaces = ['registry'] accepts = [ Mixed(Parameter(str, "Human readable name (hrn or xrn)"), Parameter(type([str]), "List of Human readable names (hrn or xrn)")), Mixed(Parameter(str, "Credential string"), Parameter(type([str]), "List of credentials")), ] returns = [Parameter(dict, "Dictionary of gids keyed on hrn")] def call(self, xrns, creds): # validate the credential valid_creds = self.api.auth.checkCredentials(creds, 'getgids') # xxxpylintxxx origin_hrn is unused.. origin_hrn = Credential(string=valid_creds[0]).get_gid_caller().get_hrn() # resolve the record records = self.api.manager.Resolve(self.api, xrns, details = False) if not records: raise RecordNotFound(xrns) allowed_fields = ['hrn', 'type', 'gid'] for record in records: for key in record.keys(): if key not in allowed_fields: del(record[key]) return records
class GetTicket(Method): """ Retrieve a ticket. This operation is currently implemented on PLC only (see SFA, engineering decisions); it is not implemented on components. The ticket is filled in with information from the PLC database. This information includes resources, and attributes such as user keys and initscripts. @param cred credential string @param name name of the slice to retrieve a ticket for (hrn or urn) @param rspec resource specification dictionary @return the string representation of a ticket object """ interfaces = ['aggregate', 'slicemgr'] accepts = [ Parameter(str, "Human readable name of slice to retrive a ticket for (hrn or urn)"), Mixed(Parameter(str, "Credential string"), Parameter(type([str]), "List of credentials")), Parameter(str, "Resource specification (rspec)"), Parameter(type([]), "List of user information"), Parameter(dict, "Options") ] returns = Parameter(str, "String representation of a ticket object") def call(self, xrn, creds, rspec, users, options): hrn, type = urn_to_hrn(xrn) # Find the valid credentials valid_creds = self.api.auth.checkCredentials(creds, 'getticket', hrn) origin_hrn = Credential(string=valid_creds[0]).get_gid_caller().get_hrn() #log the call self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, hrn, self.name)) # filter rspec through foam.sfa.ables if self.api.interface in ['aggregate']: chain_name = 'OUTGOING' elif self.api.interface in ['slicemgr']: chain_name = 'FORWARD-OUTGOING' rspec = run_foam.sfa.ables(chain_name, hrn, origin_hrn, rspec) # remove nodes that are not available at this interface from the rspec return self.api.manager.GetTicket(self.api, xrn, creds, rspec, users, options)
class CreateGid(Method): """ Create a signed credential for the s object with the registry. In addition to being stored in the SFA database, the appropriate records will also be created in the PLC databases @param xrn urn or hrn of certificate owner @param cert caller's certificate @param cred credential string @return gid string representation """ interfaces = ['registry'] accepts = [ Mixed(Parameter(str, "Credential string"), Parameter(type([str]), "List of credentials")), Parameter(str, "URN or HRN of certificate owner"), Parameter(str, "Certificate string"), ] returns = Parameter(int, "String representation of gid object") def call(self, creds, xrn, cert=None): # TODO: is there a better right to check for or is 'update good enough? valid_creds = self.api.auth.checkCredentials(creds, 'update') # verify permissions hrn, type = urn_to_hrn(xrn) self.api.auth.verify_object_permission(hrn) #log the call origin_hrn = Credential(string=valid_creds[0]).get_gid_caller().get_hrn() # log origin_hrn = Credential(string=valid_creds[0]).get_gid_caller().get_hrn() self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, xrn, self.name)) return self.api.manager.CreateGid(self.api, xrn, cert)
class Register(Method): """ Register an object with the registry. In addition to being stored in the SFA database, the appropriate records will also be created in the PLC databases @param cred credential string @param record_dict dictionary containing record fields @return gid string representation """ interfaces = ['registry'] accepts = [ Parameter(dict, "Record dictionary containing record fields"), Mixed(Parameter(str, "Credential string"), Parameter(type([str]), "List of credentials")), ] returns = Parameter(int, "String representation of gid object") def call(self, record, creds): # validate cred valid_creds = self.api.auth.checkCredentials(creds, 'register') # verify permissions hrn = record.get('hrn', '') self.api.auth.verify_object_permission(hrn) #log the call origin_hrn = Credential( string=valid_creds[0]).get_gid_caller().get_hrn() self.api.logger.info( "interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s" % (self.api.interface, origin_hrn, hrn, self.name)) return self.api.manager.Register(self.api, record)
class GetSelfCredential(Method): """ Retrive a credential for an object @param cert certificate string @param type type of object (user | slice | sa | ma | node) @param hrn human readable name of object (hrn or urn) @return the string representation of a credential object """ interfaces = ['registry'] accepts = [ Parameter(str, "certificate"), Parameter(str, "Human readable name (hrn or urn)"), Mixed(Parameter(str, "Record type"), Parameter(None, "Type not specified")), ] returns = Parameter(str, "String representation of a credential object") def call(self, cert, xrn, type): """ GetSelfCredential a degenerate version of GetCredential used by a client to get his initial credential when de doesnt have one. This is the same as GetCredential(..., cred = None, ...) The registry ensures that the client is the principal that is named by (type, name) by comparing the public key in the record's GID to the private key used to encrypt the client side of the HTTPS connection. Thus it is impossible for one principal to retrieve another principal's credential without having the appropriate private key. @param type type of object (user | slice | sa | ma | node) @param hrn human readable name of authority to list @return string representation of a credential object """ if type: hrn = urn_to_hrn(xrn)[0] else: hrn, type = urn_to_hrn(xrn) self.api.auth.verify_object_belongs_to_me(hrn) origin_hrn = Certificate(string=cert).get_subject() self.api.logger.info( "interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s" % (self.api.interface, origin_hrn, hrn, self.name)) ### authenticate the gid # import here so we can load this module at build-time for foam.sfa.wsdl #from foam.sfa.storage.alchemy import dbsession from foam.sfa.storage.model import RegRecord # xxx-local - the current code runs Resolve, which would forward to # another registry if needed # I wonder if this is truly the intention, or shouldn't we instead # only look in the local db ? records = self.api.manager.Resolve(self.api, xrn, type, details=False) if not records: raise RecordNotFound(hrn) record_obj = RegRecord(dict=records[0]) # xxx-local the local-only version would read #record_obj = dbsession.query(RegRecord).filter_by(hrn=hrn).first() #if not record_obj: raise RecordNotFound(hrn) gid = record_obj.get_gid_object() gid_str = gid.save_to_string(save_parents=True) self.api.auth.authenticateGid(gid_str, [cert, type, hrn]) # authenticate the certificate against the gid in the db certificate = Certificate(string=cert) if not certificate.is_pubkey(gid.get_pubkey()): for (obj, name) in [ (certificate, "CERT"), (gid, "GID"), ]: self.api.logger.debug( "ConnectionKeyGIDMismatch, %s pubkey: %s" % (name, obj.get_pubkey().get_pubkey_string())) self.api.logger.debug("ConnectionKeyGIDMismatch, %s dump: %s" % (name, obj.dump_string())) if hasattr(obj, 'filename'): self.api.logger.debug( "ConnectionKeyGIDMismatch, %s filename: %s" % (name, obj.filename)) raise ConnectionKeyGIDMismatch(gid.get_subject()) return self.api.manager.GetCredential(self.api, xrn, type)