X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fclient%2Fsfi.py;h=3699d55586f0bc2c5c717302241c543075b9890d;hb=27e30f7854884928bd4850afa3c6ce5c7f93f7f4;hp=e55753727ad47afc9643bab2fd6e2c77171113ca;hpb=2c090a609d05729b8fc1328adfc9deb0885218a8;p=sfa.git diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py index e5575372..3699d555 100644 --- a/sfa/client/sfi.py +++ b/sfa/client/sfi.py @@ -31,6 +31,7 @@ from sfa.util.xrn import get_leaf, get_authority, hrn_to_urn, Xrn from sfa.util.config import Config from sfa.util.version import version_core from sfa.util.cache import Cache +from sfa.util.printable import printable from sfa.storage.record import Record @@ -95,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): @@ -200,15 +201,15 @@ 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, 'researchers') and options.researchers: - record_dict['researcher'] = options.researchers + 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 - if hasattr(options, 'pis') and options.pis: - record_dict['pi'] = options.pis + if hasattr(options, 'reg_pis') and options.reg_pis: + record_dict['reg-pis'] = options.reg_pis # handle extra settings record_dict.update(options.extras) @@ -241,18 +242,29 @@ from functools import wraps commands_list=[] commands_dict={} -def register_command (args_string, example): +def declare_command (args_string, example,aliases=None): def wrap(m): name=getattr(m,'__name__') doc=getattr(m,'__doc__',"-- missing doc --") doc=doc.strip(" \t\n") commands_list.append(name) - commands_dict[name]=(doc, args_string, example) + # last item is 'canonical' name, so we can know which commands are aliases + command_tuple=(doc, args_string, example,name) + commands_dict[name]=command_tuple + if aliases is not None: + for alias in aliases: + commands_list.append(alias) + commands_dict[alias]=command_tuple @wraps(m) def new_method (*args, **kwds): return m(*args, **kwds) 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: @@ -292,7 +304,8 @@ class Sfi: ### suitable if no reasonable command has been provided def print_commands_help (self, options): verbose=getattr(options,'verbose') - format3="%18s %-15s %s" + format3="%10s %-35s %s" + format3offset=47 line=80*'-' if not verbose: print format3%("command","cmd_args","description") @@ -302,19 +315,29 @@ class Sfi: self.create_parser_global().print_help() # preserve order from the code for command in commands_list: - (doc, args_string, example) = commands_dict[command] + try: + (doc, args_string, example, canonical) = commands_dict[command] + except: + print "Cannot find info on command %s - skipped"%command + continue if verbose: print line - doc=doc.replace("\n","\n"+35*' ') - print format3%(command,args_string,doc) - if verbose: - self.create_parser_command(command).print_help() + if command==canonical: + doc=doc.replace("\n","\n"+format3offset*' ') + print format3%(command,args_string,doc) + if verbose: + self.create_parser_command(command).print_help() + else: + print format3%(command,"<>"%canonical,"") ### now if a known command was found we can be more verbose on that one def print_help (self): print "==================== Generic sfi usage" self.sfi_parser.print_help() - (doc,_,example)=commands_dict[self.command] + (doc,_,example,canonical)=commands_dict[self.command] + if canonical != self.command: + print "\n==================== NOTE: %s is an alias for genuine %s"%(self.command,canonical) + self.command=canonical print "\n==================== Purpose of %s"%self.command print doc print "\n==================== Specific usage for %s"%self.command @@ -374,7 +397,7 @@ class Sfi: sys.exit(2) # retrieve args_string - (_, args_string, __) = commands_dict[command] + (_, args_string, __,canonical) = commands_dict[command] parser = OptionParser(add_help_option=False, usage="sfi [sfi_options] %s [cmd_options] %s" @@ -382,21 +405,21 @@ class Sfi: parser.add_option ("-h","--help",dest='help',action='store_true',default=False, help="Summary of one command usage") - if command in ("config"): + if canonical in ("config"): parser.add_option('-m', '--myslice', dest='myslice', action='store_true', default=False, help='how myslice config variables as well') - if command in ("version"): + if canonical in ("version"): parser.add_option("-l","--local", action="store_true", dest="version_local", default=False, help="display version of the local client") - if command in ("version", "trusted"): + if canonical in ("version", "trusted"): parser.add_option("-R","--registry_interface", action="store_true", dest="registry_interface", default=False, help="target the registry interface instead of slice interface") - if command in ("add", "update"): + if canonical in ("register", "update"): 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)") @@ -404,17 +427,17 @@ class Sfi: default=None) parser.add_option('-s', '--slices', dest='slices', metavar='', help='Set/replace slice xrns', default='', type="str", action='callback', callback=optparse_listvalue_callback) - parser.add_option('-r', '--researchers', dest='researchers', metavar='', - help='Set/replace slice researchers', default='', type="str", action='callback', + parser.add_option('-r', '--researchers', dest='reg_researchers', metavar='', + help='Set/replace slice researchers - use -r none to reset', default=None, type="str", action='callback', callback=optparse_listvalue_callback) - parser.add_option('-p', '--pis', dest='pis', metavar='', help='Set/replace Principal Investigators/Project Managers', + parser.add_option('-p', '--pis', dest='reg_pis', metavar='', help='Set/replace Principal Investigators/Project Managers', default='', type="str", action='callback', callback=optparse_listvalue_callback) parser.add_option ('-X','--extra',dest='extras',default={},type='str',metavar="", action="callback", callback=optparse_dictvalue_callback, nargs=1, help="set extra/testbed-dependent flags, e.g. --extra enabled=true") # user specifies remote aggregate/sm/component - if command in ("resources", "describe", "allocate", "provision", "delete", "allocate", "provision", + if canonical in ("resources", "describe", "allocate", "provision", "delete", "allocate", "provision", "action", "shutdown", "renew", "status"): parser.add_option("-d", "--delegate", dest="delegate", default=None, action="store_true", @@ -422,19 +445,24 @@ class Sfi: "authority in set of credentials for this call") # show_credential option - if command in ("list","resources", "describe", "provision", "allocate", "add","update","remove","delete","status","renew"): + 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 command in ("list", "show", "remove"): + if canonical in ("list", "show", "remove"): parser.add_option("-t", "--type", dest="type", type="choice", help="type filter ([all]|user|slice|authority|node|aggregate)", choices=("all", "user", "slice", "authority", "node", "aggregate"), default="all") - if command in ("show"): + if canonical in ("show"): parser.add_option("-k","--key",dest="keys",action="append",default=[], help="specify specific keys to be displayed from record") - if command in ("resources", "describe"): + parser.add_option("-n","--no-details",dest="no_details",action="store_true",default=False, + help="call Resolve without the 'details' option") + if canonical in ("resources", "describe"): # rspec version parser.add_option("-r", "--rspec-version", dest="rspec_version", default="GENI 3", help="schema type and version of resulting RSpec") @@ -455,11 +483,11 @@ class Sfi: choices=("all", "resources", "leases"), default="resources") - if command in ("resources", "describe", "allocate", "provision", "show", "list", "gid"): + if canonical in ("resources", "describe", "allocate", "provision", "show", "list", "gid"): parser.add_option("-o", "--output", dest="file", help="output XML to file", metavar="FILE", default=None) - if command in ("show", "list"): + if canonical in ("show", "list"): parser.add_option("-f", "--format", dest="format", type="choice", help="display format ([text]|xml)", default="text", choices=("text", "xml")) @@ -467,12 +495,12 @@ class Sfi: parser.add_option("-F", "--fileformat", dest="fileformat", type="choice", help="output file format ([xml]|xmllist|hrnlist)", default="xml", choices=("xml", "xmllist", "hrnlist")) - if command == 'list': + if canonical == 'list': parser.add_option("-r", "--recursive", dest="recursive", action='store_true', help="list all child records", default=False) parser.add_option("-v", "--verbose", dest="verbose", action='store_true', help="gives details, like user keys", default=False) - if command in ("delegate"): + if canonical in ("delegate"): parser.add_option("-u", "--user", action="store_true", dest="delegate_user", default=False, help="delegate your own credentials; default if no other option is provided") @@ -480,14 +508,14 @@ class Sfi: metavar="slice_hrn", help="delegate cred. for slice HRN") parser.add_option("-a", "--auths", dest='delegate_auths',action='append',default=[], metavar='auth_hrn', help="delegate cred for auth HRN") - # this primarily is a shorthand for -a my_hrn + # this primarily is a shorthand for -A my_hrn^ parser.add_option("-p", "--pi", dest='delegate_pi', default=None, action='store_true', - help="delegate your PI credentials, so s.t. like -a your_hrn^") + help="delegate your PI credentials, so s.t. like -A your_hrn^") parser.add_option("-A","--to-authority",dest='delegate_to_authority',action='store_true',default=False, help="""by default the mandatory argument is expected to be a user, use this if you mean an authority instead""") - if command in ("myslice"): + if canonical in ("myslice"): parser.add_option("-p","--password",dest='password',action='store',default=None, help="specify mainfold password on the command line") parser.add_option("-s", "--slice", dest="delegate_slices",action='append',default=[], @@ -504,10 +532,11 @@ use this if you mean an authority instead""") # Main: parse arguments and dispatch to command # def dispatch(self, command, command_options, command_args): - method=getattr(self, command, None) + (doc, args_string, example, canonical) = commands_dict[command] + method=getattr(self, canonical, None) if not method: - print "Unknown command %s"%command - return + print "sfi: unknown command %s"%command + raise SystemExit,"Unknown command %s"%command return method(command_options, command_args) def main(self): @@ -546,14 +575,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): @@ -646,6 +674,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 @@ -841,13 +871,25 @@ 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 # # Registry-related commands #========================================================================== - @register_command("","") + @declare_command("","") def config (self, options, args): "Display contents of current config" print "# From configuration file %s"%self.config_file @@ -870,12 +912,14 @@ 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 - @register_command("","") + @declare_command("","") def version(self, options, args): """ display an SFA server version (GetVersion) - or version information about sfi itself + or version information about sfi itself """ if options.version_local: version=version_core() @@ -891,8 +935,10 @@ use this if you mean an authority instead""") else: pprinter = PrettyPrinter(indent=4) pprinter.pprint(version) + # xxx should analyze result + return 0 - @register_command("authority","") + @declare_command("authority","") def list(self, options, args): """ list entries in named authority registry (List) @@ -918,9 +964,10 @@ 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 - @register_command("name","") + @declare_command("name","") def show(self, options, args): """ show details about named registry record (Resolve) @@ -930,7 +977,9 @@ use this if you mean an authority instead""") sys.exit(1) hrn = args[0] # explicitly require Resolve to run in details mode - record_dicts = self.registry().Resolve(hrn, self.my_credential_string, {'details':True}) + resolve_options={} + if not options.no_details: resolve_options['details']=True + record_dicts = self.registry().Resolve(hrn, self.my_credential_string, resolve_options) record_dicts = filter_records(options.type, record_dicts) if not record_dicts: self.logger.error("No record of type %s"% options.type) @@ -950,13 +999,15 @@ 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 - @register_command("[xml-filename]","") - def add(self, options, args): - """add record into registry (Register) - from command line options (recommended) - old-school method involving an xml file still supported""" + # this historically was named 'add', it is now 'register' with an alias for legacy + @declare_command("[xml-filename]","",['add']) + def register(self, options, args): + """create new record in registry (Register) + from command line options (recommended) + old-school method involving an xml file still supported""" auth_cred = self.my_authority_credential_string() if options.show_credential: @@ -986,13 +1037,17 @@ 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 - @register_command("[xml-filename]","") + @declare_command("[xml-filename]","") def update(self, options, args): """update record into registry (Update) - from command line options (recommended) - old-school method involving an xml file still supported""" + from command line options (recommended) + old-school method involving an xml file still supported""" record_dict = {} if len(args) > 0: record_filepath = args[0] @@ -1007,12 +1062,12 @@ use this if you mean an authority instead""") # don't translate into an object, as this would possibly distort # user-provided data; e.g. add an 'email' field to Users - if record_dict['type'] == "user": + if record_dict['type'] in ['user']: if record_dict['hrn'] == self.user: cred = self.my_credential_string else: cred = self.my_authority_credential_string() - elif record_dict['type'] in ["slice"]: + elif record_dict['type'] in ['slice']: try: cred = self.slice_credential_string(record_dict['hrn']) except ServerException, e: @@ -1022,17 +1077,21 @@ use this if you mean an authority instead""") cred = self.my_authority_credential_string() else: raise - elif record_dict['type'] in ["authority"]: + elif record_dict['type'] in ['authority']: cred = self.my_authority_credential_string() - elif record_dict['type'] == 'node': + elif record_dict['type'] in ['node']: cred = self.my_authority_credential_string() else: 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 - @register_command("hrn","") + @declare_command("hrn","") def remove(self, options, args): "remove registry record by name (Remove)" auth_cred = self.my_authority_credential_string() @@ -1045,14 +1104,18 @@ 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 # ================================================================== # show rspec for named slice - @register_command("","") + @declare_command("","") def resources(self, options, args): """ discover available resources (ListResources) @@ -1092,22 +1155,21 @@ 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 self.success(list_resources) - return - - @register_command("slice_hrn","") + @declare_command("slice_hrn","") def describe(self, options, args): """ shows currently allocated/provisioned resources - of the named slice or set of slivers (Describe) + of the named slice or set of slivers (Describe) """ server = self.sliceapi() @@ -1124,6 +1186,9 @@ use this if you mean an authority instead""") 'list_leases': options.list_leases, 'geni_rspec_version': {'type': 'geni', 'version': '3'}, } + if options.info: + api_options['info'] = options.info + if options.rspec_version: version_manager = VersionManager() server_version = self.get_cached_server_version(server) @@ -1132,19 +1197,19 @@ 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) - @register_command("slice_hrn [ ... ]","") + @declare_command("slice_hrn [...]","") def delete(self, options, args): """ de-allocate and de-provision all or named slivers of the named slice (Delete) @@ -1171,15 +1236,15 @@ 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) - @register_command("slice_hrn rspec","") + @declare_command("slice_hrn rspec","") def allocate(self, options, args): """ allocate resources to the named slice (Allocate) @@ -1214,6 +1279,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'] @@ -1225,18 +1291,17 @@ 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) - @register_command("slice_hrn [ ... ]","") + @declare_command("slice_hrn [...]","") def provision(self, options, args): """ provision all or named already allocated slivers of the named slice (Provision) @@ -1291,17 +1356,17 @@ 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) - @register_command("slice_hrn","") + @declare_command("slice_hrn","") def status(self, options, args): """ retrieve the status of the slivers belonging to the named slice (Status) @@ -1321,16 +1386,15 @@ 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) - @register_command("slice_hrn [ ... ] action","") + @declare_command("slice_hrn [...] action","") def action(self, options, args): """ Perform the named operational action on all or named slivers of the named slice @@ -1354,15 +1418,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 - - @register_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) @@ -1389,18 +1458,19 @@ 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) - - @register_command("slice_hrn","") + @declare_command("slice_hrn","") def shutdown(self, options, args): """ shutdown named slice (Shutdown) @@ -1412,16 +1482,15 @@ 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) - @register_command("[name]","") + @declare_command("[name]","") def gid(self, options, args): """ Create a GID (CreateGid) @@ -1438,9 +1507,11 @@ 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 #################### - @register_command("to_hrn","""$ sfi delegate -u -p -s ple.inria.heartbeat -s ple.inria.omftest ple.upmc.slicebrowser + @declare_command("to_hrn","""$ sfi delegate -u -p -s ple.inria.heartbeat -s ple.inria.omftest ple.upmc.slicebrowser will locally create a set of delegated credentials for the benefit of ple.upmc.slicebrowser the set of credentials in the scope for this call would be @@ -1456,8 +1527,8 @@ use this if you mean an authority instead""") def delegate (self, options, args): """ (locally) create delegate credential for use by given hrn - make sure to check for 'sfi myslice' instead if you plan - on using MySlice + make sure to check for 'sfi myslice' instead if you plan + on using MySlice """ if len(args) != 1: self.print_help() @@ -1502,7 +1573,7 @@ use this if you mean an authority instead""") self.logger.info("delegated credential for %s to %s and wrote to %s"%(message,to_hrn,filename)) #################### - @register_command("","""$ less +/myslice sfi_config + @declare_command("","""$ less +/myslice sfi_config [myslice] backend = http://manifold.pl.sophia.inria.fr:7080 # the HRN that myslice uses, so that we are delegating to @@ -1526,15 +1597,15 @@ $ sfi m -b http://mymanifold.foo.com:7080/ is synonym to sfi myslice as no other command starts with an 'm' and uses a custom backend for this one call """ -) # register_command +) # declare_command def myslice (self, options, args): """ This helper is for refreshing your credentials at myslice; it will - * compute all the slices that you currently have credentials on - * refresh all your credentials (you as a user and pi, your slices) - * upload them to the manifold backend server - for last phase, sfi_config is read to look for the [myslice] section, - and namely the 'backend', 'delegate' and 'user' settings""" + * compute all the slices that you currently have credentials on + * refresh all your credentials (you as a user and pi, your slices) + * upload them to the manifold backend server + for last phase, sfi_config is read to look for the [myslice] section, + and namely the 'backend', 'delegate' and 'user' settings""" ########## if len(args)>0: @@ -1638,9 +1709,10 @@ $ 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 - @register_command("cred","") + @declare_command("cred","") def trusted(self, options, args): """ return the trusted certs at this interface (get_trusted_certs) @@ -1661,5 +1733,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