X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fclient%2Fsfi.py;h=a77f258f0aea51ec7c6792b070d331d071b5c818;hb=5b82b6b9ec6cd3f9ce39b26a9802268789d2f56d;hp=6bb41c9cb6761f62c8455d02fa653702483a5e9d;hpb=8a72ea951407d90bdeb05e27976197b330db4247;p=sfa.git diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py index 6bb41c9c..a77f258f 100644 --- a/sfa/client/sfi.py +++ b/sfa/client/sfi.py @@ -241,13 +241,19 @@ from functools import wraps commands_list=[] commands_dict={} -def register_command (args_string, example): +def register_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 @@ -292,7 +298,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 %-30s %s" + format3offset=42 line=80*'-' if not verbose: print format3%("command","cmd_args","description") @@ -302,19 +309,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 +391,7 @@ class Sfi: sys.exit(2) # retrieve args_string - (_, args_string, __) = commands_dict[command] + (_, args_string, __,___) = commands_dict[command] parser = OptionParser(add_help_option=False, usage="sfi [sfi_options] %s [cmd_options] %s" @@ -392,12 +409,11 @@ class Sfi: help="display version of the local client") if command in ("version", "trusted"): - parser.add_option("-I", "--interface", dest="interface", type="choice", - help="Select the SFA interface the call should target (Slice Interface (sm) | Registry Interface (registry))", - choices=("sm", "registry"), - default="sm") + 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 command 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)") @@ -423,7 +439,7 @@ 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 command 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") # registy filter option @@ -876,12 +892,12 @@ use this if you mean an authority instead""") 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() else: - if options.interface == "registry": + if options.registry_interface: server=self.registry() else: server = self.sliceapi() @@ -953,11 +969,12 @@ use this if you mean an authority instead""") save_records_to_file(options.file, record_dicts, options.fileformat) return - @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 + @register_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: @@ -992,8 +1009,8 @@ use this if you mean an authority instead""") @register_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] @@ -1108,7 +1125,7 @@ use this if you mean an authority instead""") 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() @@ -1121,10 +1138,13 @@ 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'}, } + if options.info: + api_options['info'] = options.info + if options.rspec_version: version_manager = VersionManager() server_version = self.get_cached_server_version(server) @@ -1145,10 +1165,10 @@ use this if you mean an authority instead""") return - @register_command("slice_hrn","") + @register_command("slice_hrn [...]","") def delete(self, options, args): """ - de-allocate and de-provision all or named slivers of the slice (Delete) + de-allocate and de-provision all or named slivers of the named slice (Delete) """ server = self.sliceapi() @@ -1156,6 +1176,13 @@ use this if you mean an authority instead""") slice_hrn = args[0] slice_urn = hrn_to_urn(slice_hrn, 'slice') + if len(args) > 1: + # we have sliver urns + sliver_urns = args[1:] + else: + # we provision all the slivers of the slice + sliver_urns = [slice_urn] + # creds slice_cred = self.slice_credential(slice_hrn) creds = [slice_cred] @@ -1165,7 +1192,7 @@ 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([slice_urn], creds, *self.ois(server, api_options ) ) + result = server.Delete(sliver_urns, creds, *self.ois(server, api_options ) ) value = ReturnValue.get_value(result) if self.options.raw: save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) @@ -1230,15 +1257,21 @@ use this if you mean an authority instead""") return value - @register_command("slice_hrn","") + @register_command("slice_hrn [...]","") def provision(self, options, args): """ - provision already allocated resources of named slice (Provision) + provision all or named already allocated slivers of the named slice (Provision) """ server = self.sliceapi() server_version = self.get_cached_server_version(server) slice_hrn = args[0] slice_urn = Xrn(slice_hrn, type='slice').get_urn() + if len(args) > 1: + # we have sliver urns + sliver_urns = args[1:] + else: + # we provision all the slivers of the slice + sliver_urns = [slice_urn] # credentials creds = [self.slice_credential(slice_hrn)] @@ -1279,7 +1312,7 @@ use this if you mean an authority instead""") users = pg_users_arg(user_records) api_options['geni_users'] = users - result = server.Provision([slice_urn], creds, api_options) + result = server.Provision(sliver_urns, creds, api_options) value = ReturnValue.get_value(result) if self.options.raw: save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) @@ -1292,7 +1325,7 @@ use this if you mean an authority instead""") @register_command("slice_hrn","") def status(self, options, args): """ - retrieve the status of the slivers belonging to tne named slice (Status) + retrieve the status of the slivers belonging to the named slice (Status) """ server = self.sliceapi() @@ -1318,17 +1351,23 @@ use this if you mean an authority instead""") # Thierry: seemed to be missing return value - @register_command("slice_hrn action","") + @register_command("slice_hrn [...] action","") def action(self, options, args): """ - Perform the named operational action on these slivers + Perform the named operational action on all or named slivers of the named slice """ server = self.sliceapi() api_options = {} # slice urn slice_hrn = args[0] - action = args[1] - slice_urn = Xrn(slice_hrn, type='slice').get_urn() + slice_urn = Xrn(slice_hrn, type='slice').get_urn() + if len(args) > 2: + # we have sliver urns + sliver_urns = args[1:-1] + else: + # we provision all the slivers of the slice + sliver_urns = [slice_urn] + action = args[-1] # cred slice_cred = self.slice_credential(args[0]) creds = [slice_cred] @@ -1336,7 +1375,7 @@ 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([slice_urn], creds, action , api_options) + result = server.PerformOperationalAction(sliver_urns, creds, action , api_options) value = ReturnValue.get_value(result) if self.options.raw: save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) @@ -1344,18 +1383,26 @@ use this if you mean an authority instead""") print value return value - @register_command("slice_hrn time","") + @register_command("slice_hrn [...] time","") def renew(self, options, args): """ - renew slice (RenewSliver) + renew slice (Renew) """ server = self.sliceapi() - if len(args) != 2: + if len(args) < 2: self.print_help() sys.exit(1) - [ slice_hrn, input_time ] = args - # slice urn - slice_urn = hrn_to_urn(slice_hrn, 'slice') + slice_hrn = args[0] + slice_urn = Xrn(slice_hrn, type='slice').get_urn() + + if len(args) > 2: + # we have sliver urns + sliver_urns = args[1:-1] + else: + # we provision all the slivers of the slice + sliver_urns = [slice_urn] + input_time = args[-1] + # time: don't try to be smart on the time format, server-side will # creds slice_cred = self.slice_credential(args[0]) @@ -1365,7 +1412,7 @@ use this if you mean an authority instead""") api_options['call_id']=unique_call_id() if options.show_credential: show_credentials(creds) - result = server.Renew([slice_urn], creds, input_time, *self.ois(server,api_options)) + result = server.Renew(sliver_urns, creds, input_time, *self.ois(server,api_options)) value = ReturnValue.get_value(result) if self.options.raw: save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) @@ -1430,8 +1477,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() @@ -1504,11 +1551,11 @@ $ sfi m -b http://mymanifold.foo.com:7080/ 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: @@ -1619,13 +1666,13 @@ $ sfi m -b http://mymanifold.foo.com:7080/ """ return the trusted certs at this interface (get_trusted_certs) """ - if options.interface == "registry": + if options.registry_interface: server=self.registry() else: server = self.sliceapi() cred = self.my_authority_credential_string() trusted_certs = server.get_trusted_certs(cred) - if options.interface != "registry": + if not options.registry_interface: trusted_certs = ReturnValue.get_value(trusted_certs) for trusted_cert in trusted_certs: