X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fclient%2Fsfi.py;h=31b8a0530ac144da14d88d080842323ca65769f6;hb=a5fdefe7f034410ab55ba0d739c2b802334418e9;hp=49156ec2532142f5e086a2471f2d2c179dc66940;hpb=146e88ac4121461b1d0c625c2f6b16c84b9f7e85;p=sfa.git diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py index 49156ec2..31b8a053 100644 --- a/sfa/client/sfi.py +++ b/sfa/client/sfi.py @@ -96,14 +96,14 @@ def filter_records(type, records): def credential_printable (cred): - credential=Credential(cred=cred) + credential = Credential(cred=cred) result="" - result += credential.get_summary_tostring() + result += credential.pretty_cred() result += "\n" rights = credential.get_privileges() result += "type=%s\n" % credential.type result += "version=%s\n" % credential.version - result += "rights=%s\n"%rights + result += "rights=%s\n" % rights return result def show_credentials (cred_s): @@ -201,13 +201,16 @@ def load_record_from_opts(options): pubkey = options.key if not check_ssh_key (pubkey): raise SfaInvalidArgument(name='key',msg="Could not find file, or wrong key format") - record_dict['keys'] = [pubkey] + record_dict['reg-keys'] = [pubkey] if hasattr(options, 'slices') and options.slices: record_dict['slices'] = options.slices if hasattr(options, 'reg_researchers') and options.reg_researchers is not None: record_dict['reg-researchers'] = options.reg_researchers if hasattr(options, 'email') and options.email: record_dict['email'] = options.email + # authorities can have a name for standalone deployment + if hasattr(options, 'name') and options.name: + record_dict['name'] = options.name if hasattr(options, 'reg_pis') and options.reg_pis: record_dict['reg-pis'] = options.reg_pis @@ -260,6 +263,11 @@ def declare_command (args_string, example,aliases=None): return new_method return wrap + +def remove_none_fields (record): + none_fields=[ k for (k,v) in record.items() if v is None ] + for k in none_fields: del record[k] + ########## class Sfi: @@ -418,6 +426,7 @@ class Sfi: parser.add_option('-x', '--xrn', dest='xrn', metavar='', help='object hrn/urn (mandatory)') parser.add_option('-t', '--type', dest='type', metavar='', help='object type', default=None) parser.add_option('-e', '--email', dest='email', default="", help="email (mandatory for users)") + parser.add_option('-n', '--name', dest='name', default="", help="name (optional for authorities)") parser.add_option('-k', '--key', dest='key', metavar='', help='public key string or file', default=None) parser.add_option('-s', '--slices', dest='slices', metavar='', help='Set/replace slice xrns', @@ -443,6 +452,9 @@ class Sfi: if canonical in ("list","resources", "describe", "provision", "allocate", "register","update","remove","delete","status","renew"): parser.add_option("-C","--credential",dest='show_credential',action='store_true',default=False, help="show credential(s) used in human-readable form") + if canonical in ("renew"): + parser.add_option("-l","--as-long-as-possible",dest='alap',action='store_true',default=False, + help="renew as long as possible") # registy filter option if canonical in ("list", "show", "remove"): parser.add_option("-t", "--type", dest="type", type="choice", @@ -567,14 +579,13 @@ use this if you mean an authority instead""") self.logger.debug("Command=%s" % self.command) try: - self.dispatch(command, command_options, command_args) + retcod = self.dispatch(command, command_options, command_args) except SystemExit: return 1 except: self.logger.log_exc ("sfi command %s failed"%command) return 1 - - return 0 + return retcod #################### def read_config(self): @@ -667,6 +678,8 @@ use this if you mean an authority instead""") # init self-signed cert, user credentials and gid def bootstrap (self): + if self.options.verbose: + self.logger.info("Initializing SfaClientBootstrap with {}".format(self.reg_url)) client_bootstrap = SfaClientBootstrap (self.user, self.reg_url, self.options.sfi_dir, logger=self.logger) # if -k is provided, use this to initialize private key @@ -862,6 +875,18 @@ use this if you mean an authority instead""") sys.exit(1) + # helper function to analyze raw output + # for main : return 0 if everything is fine, something else otherwise (mostly 1 for now) + def success (self, raw): + return_value=ReturnValue (raw) + output=ReturnValue.get_output(return_value) + # means everything is fine + if not output: + return 0 + # something went wrong + print 'ERROR:',output + return 1 + #========================================================================== # Following functions implement the commands # @@ -891,6 +916,8 @@ use this if you mean an authority instead""") varname="%s_%s"%(section.upper(),name.upper()) value=getattr(self.config_instance,varname) print "%-20s = %s"%(name,value) + # xxx should analyze result + return 0 @declare_command("","") def version(self, options, args): @@ -912,6 +939,8 @@ use this if you mean an authority instead""") else: pprinter = PrettyPrinter(indent=4) pprinter.pprint(version) + # xxx should analyze result + return 0 @declare_command("authority","") def list(self, options, args): @@ -939,7 +968,8 @@ use this if you mean an authority instead""") terminal_render (list, options) if options.file: save_records_to_file(options.file, list, options.fileformat) - return + # xxx should analyze result + return 0 @declare_command("name","") def show(self, options, args): @@ -973,7 +1003,8 @@ use this if you mean an authority instead""") else: print record.save_as_xml() if options.file: save_records_to_file(options.file, record_dicts, options.fileformat) - return + # xxx should analyze result + return 0 # this historically was named 'add', it is now 'register' with an alias for legacy @declare_command("[xml-filename]","",['add']) @@ -1010,7 +1041,11 @@ use this if you mean an authority instead""") record_dict['first_name'] = record_dict['hrn'] if 'last_name' not in record_dict: record_dict['last_name'] = record_dict['hrn'] - return self.registry().Register(record_dict, auth_cred) + register = self.registry().Register(record_dict, auth_cred) + # xxx looks like the result here is not ReturnValue-compatible + #return self.success (register) + # xxx should analyze result + return 0 @declare_command("[xml-filename]","") def update(self, options, args): @@ -1054,7 +1089,11 @@ use this if you mean an authority instead""") raise "unknown record type" + record_dict['type'] if options.show_credential: show_credentials(cred) - return self.registry().Update(record_dict, cred) + update = self.registry().Update(record_dict, cred) + # xxx looks like the result here is not ReturnValue-compatible + #return self.success(update) + # xxx should analyze result + return 0 @declare_command("hrn","") def remove(self, options, args): @@ -1069,7 +1108,11 @@ use this if you mean an authority instead""") type = '*' if options.show_credential: show_credentials(auth_cred) - return self.registry().Remove(hrn, auth_cred, type) + remove = self.registry().Remove(hrn, auth_cred, type) + # xxx looks like the result here is not ReturnValue-compatible + #return self.success (remove) + # xxx should analyze result + return 0 # ================================================================== # Slice-related commands @@ -1116,16 +1159,15 @@ use this if you mean an authority instead""") api_options['geni_rspec_version'] = {'type': 'geni', 'version': '3'} else: api_options['geni_rspec_version'] = {'type': 'geni', 'version': '3'} - result = server.ListResources (creds, api_options) - value = ReturnValue.get_value(result) + list_resources = server.ListResources (creds, api_options) + value = ReturnValue.get_value(list_resources) if self.options.raw: - save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + save_raw_to_file(list_resources, self.options.raw, self.options.rawformat, self.options.rawbanner) if options.file is not None: save_rspec_to_file(value, options.file) if (self.options.raw is None) and (options.file is None): display_rspec(value, options.format) - - return + return self.success(list_resources) @declare_command("slice_hrn","") def describe(self, options, args): @@ -1144,7 +1186,7 @@ use this if you mean an authority instead""") api_options = {'call_id': unique_call_id(), 'cached': True, - #'info': options.info, + 'info': options.info, 'list_leases': options.list_leases, 'geni_rspec_version': {'type': 'geni', 'version': '3'}, } @@ -1159,17 +1201,17 @@ use this if you mean an authority instead""") api_options['geni_rspec_version'] = version_manager.get_version(options.rspec_version).to_dict() else: api_options['geni_rspec_version'] = {'type': 'geni', 'version': '3'} - urn = Xrn(args[0], type='slice').get_urn() - result = server.Describe([urn], creds, api_options) - value = ReturnValue.get_value(result) + urn = Xrn(args[0], type='slice').get_urn() + remove_none_fields(api_options) + describe = server.Describe([urn], creds, api_options) + value = ReturnValue.get_value(describe) if self.options.raw: - save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + save_raw_to_file(describe, self.options.raw, self.options.rawformat, self.options.rawbanner) if options.file is not None: save_rspec_to_file(value['geni_rspec'], options.file) if (self.options.raw is None) and (options.file is None): - display_rspec(value, options.format) - - return + display_rspec(value['geni_rspec'], options.format) + return self.success (describe) @declare_command("slice_hrn [...]","") def delete(self, options, args): @@ -1198,13 +1240,13 @@ use this if you mean an authority instead""") api_options ['call_id'] = unique_call_id() if options.show_credential: show_credentials(creds) - result = server.Delete(sliver_urns, creds, *self.ois(server, api_options ) ) - value = ReturnValue.get_value(result) + delete = server.Delete(sliver_urns, creds, *self.ois(server, api_options ) ) + value = ReturnValue.get_value(delete) if self.options.raw: - save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + save_raw_to_file(delete, self.options.raw, self.options.rawformat, self.options.rawbanner) else: print value - return value + return self.success (delete) @declare_command("slice_hrn rspec","") def allocate(self, options, args): @@ -1241,6 +1283,7 @@ use this if you mean an authority instead""") sfa_users = [] geni_users = [] slice_records = self.registry().Resolve(slice_urn, [self.my_credential_string]) + remove_none_fields(slice_records[0]) if slice_records and 'reg-researchers' in slice_records[0] and slice_records[0]['reg-researchers']!=[]: slice_record = slice_records[0] user_hrns = slice_record['reg-researchers'] @@ -1252,16 +1295,15 @@ use this if you mean an authority instead""") api_options['sfa_users'] = sfa_users api_options['geni_users'] = geni_users - result = server.Allocate(slice_urn, creds, rspec, api_options) - value = ReturnValue.get_value(result) + allocate = server.Allocate(slice_urn, creds, rspec, api_options) + value = ReturnValue.get_value(allocate) if self.options.raw: - save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + save_raw_to_file(allocate, self.options.raw, self.options.rawformat, self.options.rawbanner) if options.file is not None: save_rspec_to_file (value['geni_rspec'], options.file) if (self.options.raw is None) and (options.file is None): print value - return value - + return self.success(allocate) @declare_command("slice_hrn [...]","") def provision(self, options, args): @@ -1318,15 +1360,15 @@ use this if you mean an authority instead""") users = pg_users_arg(user_records) api_options['geni_users'] = users - result = server.Provision(sliver_urns, creds, api_options) - value = ReturnValue.get_value(result) + provision = server.Provision(sliver_urns, creds, api_options) + value = ReturnValue.get_value(provision) if self.options.raw: - save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + save_raw_to_file(provision, self.options.raw, self.options.rawformat, self.options.rawbanner) if options.file is not None: save_rspec_to_file (value['geni_rspec'], options.file) if (self.options.raw is None) and (options.file is None): print value - return value + return self.success(provision) @declare_command("slice_hrn","") def status(self, options, args): @@ -1348,14 +1390,13 @@ use this if you mean an authority instead""") api_options['call_id']=unique_call_id() if options.show_credential: show_credentials(creds) - result = server.Status([slice_urn], creds, *self.ois(server,api_options)) - value = ReturnValue.get_value(result) + status = server.Status([slice_urn], creds, *self.ois(server,api_options)) + value = ReturnValue.get_value(status) if self.options.raw: - save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + save_raw_to_file(status, self.options.raw, self.options.rawformat, self.options.rawbanner) else: print value - # Thierry: seemed to be missing - return value + return self.success (status) @declare_command("slice_hrn [...] action","") def action(self, options, args): @@ -1381,15 +1422,20 @@ use this if you mean an authority instead""") delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority)) creds.append(delegated_cred) - result = server.PerformOperationalAction(sliver_urns, creds, action , api_options) - value = ReturnValue.get_value(result) + perform_action = server.PerformOperationalAction(sliver_urns, creds, action , api_options) + value = ReturnValue.get_value(perform_action) if self.options.raw: - save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + save_raw_to_file(perform_action, self.options.raw, self.options.rawformat, self.options.rawbanner) else: print value - return value - - @declare_command("slice_hrn [...] time","") + return self.success (perform_action) + + @declare_command("slice_hrn [...] time", + "\n".join(["sfi renew onelab.ple.heartbeat 2015-04-31", + "sfi renew onelab.ple.heartbeat 2015-04-31T14:00:00Z", + "sfi renew onelab.ple.heartbeat +5d", + "sfi renew onelab.ple.heartbeat +3w", + "sfi renew onelab.ple.heartbeat +2m",])) def renew(self, options, args): """ renew slice (Renew) @@ -1416,16 +1462,17 @@ use this if you mean an authority instead""") # options and call_id when supported api_options = {} api_options['call_id']=unique_call_id() + if options.alap: + api_options['geni_extend_alap']=True if options.show_credential: show_credentials(creds) - result = server.Renew(sliver_urns, creds, input_time, *self.ois(server,api_options)) - value = ReturnValue.get_value(result) + renew = server.Renew(sliver_urns, creds, input_time, *self.ois(server,api_options)) + value = ReturnValue.get_value(renew) if self.options.raw: - save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + save_raw_to_file(renew, self.options.raw, self.options.rawformat, self.options.rawbanner) else: print value - return value - + return self.success(renew) @declare_command("slice_hrn","") def shutdown(self, options, args): @@ -1439,14 +1486,13 @@ use this if you mean an authority instead""") # creds slice_cred = self.slice_credential(slice_hrn) creds = [slice_cred] - result = server.Shutdown(slice_urn, creds) - value = ReturnValue.get_value(result) + shutdown = server.Shutdown(slice_urn, creds) + value = ReturnValue.get_value(shutdown) if self.options.raw: - save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + save_raw_to_file(shutdown, self.options.raw, self.options.rawformat, self.options.rawbanner) else: print value - return value - + return self.success (shutdown) @declare_command("[name]","") def gid(self, options, args): @@ -1465,6 +1511,8 @@ use this if you mean an authority instead""") filename = os.sep.join([self.options.sfi_dir, '%s.gid' % target_hrn]) self.logger.info("writing %s gid to %s" % (target_hrn, filename)) GID(string=gid).save_to_file(filename) + # xxx should analyze result + return 0 #################### @declare_command("to_hrn","""$ sfi delegate -u -p -s ple.inria.heartbeat -s ple.inria.omftest ple.upmc.slicebrowser @@ -1665,7 +1713,8 @@ $ sfi m -b http://mymanifold.foo.com:7080/ # it is probably not helpful as people would not # need to run 'sfi delegate' at all anymore if count_success != count_all: sys.exit(1) - return + # xxx should analyze result + return 0 @declare_command("cred","") def trusted(self, options, args): @@ -1688,5 +1737,5 @@ $ sfi m -b http://mymanifold.foo.com:7080/ cert = Certificate(string=trusted_cert) self.logger.debug('Sfi.trusted -> %r'%cert.get_subject()) print "Certificate:\n%s\n\n"%trusted_cert - return - + # xxx should analyze result + return 0