From: Tony Mack Date: Tue, 16 Aug 2011 20:10:37 +0000 (-0400) Subject: Added CreateGid() method to Registry interface X-Git-Tag: sfa-1.0-32~2 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=3935901ee1fe60a9e29f26666bfcdeb8dcd1d9a6;p=sfa.git Added CreateGid() method to Registry interface --- diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py index 6e0c82cd..764ce18c 100755 --- a/sfa/client/sfi.py +++ b/sfa/client/sfi.py @@ -154,6 +154,7 @@ class Sfi: "update": "record", "aggregates": "[name]", "registries": "[name]", + "create_gid": "[name]", "get_gid": [], "get_trusted_certs": "cred", "slices": "", @@ -217,7 +218,7 @@ class Sfi: help="optional component information", default=None) - if command in ("resources", "show", "list"): + if command in ("resources", "show", "list", "create_gid"): parser.add_option("-o", "--output", dest="file", help="output XML to file", metavar="FILE", default=None) @@ -275,7 +276,7 @@ class Sfi: parser.add_option("-k", "--hashrequest", action="store_true", dest="hashrequest", default=False, help="Create a hash of the request that will be authenticated on the server") - parser.add_option("-t", "--timeout", dest="timeout", default=30, + parser.add_option("-t", "--timeout", dest="timeout", default=None, help="Amout of time tom wait before timing out the request") parser.disable_interspersed_args() @@ -645,7 +646,22 @@ class Sfi: def dispatch(self, command, cmd_opts, cmd_args): return getattr(self, command)(cmd_opts, cmd_args) - + + def create_gid(self, opts, args): + if len(args) < 1: + self.print_help() + sys.exit(1) + target_hrn = args[0] + user_cred = self.get_user_cred().save_to_string(save_parents=True) + gid = self.registry.CreateGid(user_cred, target_hrn, self.cert.save_to_string()) + if opts.file: + filename = opts.file + else: + filename = os.sep.join([self.sfi_dir, '%s.gid' % target_hrn]) + self.logger.info("writing %s gid to %s" % (target_hrn, filename)) + GID(string=gid).save_to_file(filename) + + # list entires in named authority registry def list(self, opts, args): if len(args)!= 1: @@ -696,7 +712,6 @@ class Sfi: record.dump() else: print record.save_to_string() - if opts.file: file = opts.file if not file.startswith(os.sep): @@ -926,6 +941,8 @@ class Sfi: # created named slice with given rspec def create(self, opts, args): + server = self.get_server_from_opts(opts) + server_version = self.get_cached_server_version(server) slice_hrn = args[0] slice_urn = hrn_to_urn(slice_hrn, 'slice') user_cred = self.get_user_cred() @@ -937,29 +954,40 @@ class Sfi: rspec_file = self.get_rspec_file(args[1]) rspec = open(rspec_file).read() + # need to pass along user keys to the aggregate. # users = [ # { urn: urn:publicid:IDN+emulab.net+user+alice # keys: [, ] # }] users = [] - server = self.get_server_from_opts(opts) - version = self.get_cached_server_version(server) - if 'sfa' not in version: - # need to pass along user keys if this request is going to a ProtoGENI aggregate + all_keys = [] + all_key_ids = [] + slice_records = self.registry.Resolve(slice_urn, [user_cred.save_to_string(save_parents=True)]) + if slice_records and 'researcher' in slice_records[0]: + slice_record = slice_records[0] + user_hrns = slice_record['researcher'] + user_urns = [hrn_to_urn(hrn, 'user') for hrn in user_hrns] + user_records = self.registry.Resolve(user_urns, [user_cred.save_to_string(save_parents=True)]) + for user_record in user_records: + #user = {'urn': user_cred.get_gid_caller().get_urn(),'keys': []} + user = {'urn': user_cred.get_gid_caller().get_urn(), # + 'keys': user_record['keys'], + 'email': user_record['email'], # needed for MyPLC + 'person_id': user_record['person_id'], # needed for MyPLC + 'first_name': user_record['first_name'], # needed for MyPLC + 'last_name': user_record['last_name'], # needed for MyPLC + 'slice_record': slice_record, # needed for legacy refresh peer + 'key_ids': user_record['key_ids'] # needed for legacy refresh peer + } + users.append(user) + all_keys.extend(user_record['keys']) + all_key_ids.extend(user_record['key_ids']) # ProtoGeni Aggregates will only install the keys of the user that is issuing the - # request. So we will only pass in one user that contains the keys for all - # users of the slice - user = {'urn': user_cred.get_gid_caller().get_urn(), - 'keys': []} - slice_record = self.registry.Resolve(slice_urn, creds) - if slice_record and 'researchers' in slice_record: - user_hrns = slice_record['researchers'] - user_urns = [hrn_to_urn(hrn, 'user') for hrn in user_hrns] - user_records = self.registry.Resolve(user_urns, creds) - for user_record in user_records: - if 'keys' in user_record: - user['keys'].extend(user_record['keys']) - users.append(user) + # request. So we will add all to the current caller's list of keys + if 'sfa' not in server_version: + for user in users: + if user['urn'] == user_cred.get_gid_caller().get_urn(): + user['keys'] = all_keys call_args = [slice_urn, creds, rspec, users] if self.server_supports_call_id_arg(server): diff --git a/sfa/managers/registry_manager_pl.py b/sfa/managers/registry_manager_pl.py index e20be089..6052eee3 100644 --- a/sfa/managers/registry_manager_pl.py +++ b/sfa/managers/registry_manager_pl.py @@ -178,8 +178,13 @@ def create_gid(api, xrn, cert): # get the authority authority = Xrn(xrn=xrn).get_authority_hrn() auth_info = api.auth.get_auth_info(authority) - - + if not cert: + pkey = Keypair(create=True) + else: + certificate = Certificate(string=cert) + pkey = certificate.get_pubkey() + gid = api.auth.hierarchy.create_gid(xrn, create_uuid(), pkey) + return gid.save_to_string(save_parents=True) def register(api, record): diff --git a/sfa/methods/CreateGid.py b/sfa/methods/CreateGid.py new file mode 100644 index 00000000..7c1bf8ac --- /dev/null +++ b/sfa/methods/CreateGid.py @@ -0,0 +1,50 @@ +### $Id: register.py 16477 2010-01-05 16:31:37Z thierry $ +### $URL: https://svn.planet-lab.org/svn/sfa/trunk/sfa/methods/register.py $ + +from sfa.util.xrn import urn_to_hrn +from sfa.util.method import Method +from sfa.util.parameter import Parameter, Mixed +from sfa.trust.credential import Credential + +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)) + + manager = self.api.get_interface_manager() + + return manager.create_gid(self.api, xrn, cert)