X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fclient%2Fsfi.py;h=e9614e90b65c18c1a06b96ec976c735ae2a7b668;hb=b7d6a80faf23cb019c74e65c2264e215446f84a3;hp=c551a8081596e699bd4f756448bdb7531e612ed7;hpb=d6f7538217350e80c6f6728dcf971bb14f2dab2a;p=sfa.git diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py index c551a808..e9614e90 100644 --- a/sfa/client/sfi.py +++ b/sfa/client/sfi.py @@ -1,8 +1,8 @@ -# +# # sfi.py - basic SFA command-line client # the actual binary in sfa/clientbin essentially runs main() # this module is used in sfascan -# +# import sys sys.path.append('.') @@ -12,6 +12,7 @@ import socket import datetime import codecs import pickle +import json from lxml import etree from StringIO import StringIO from optparse import OptionParser @@ -28,8 +29,8 @@ from sfa.util.config import Config from sfa.util.version import version_core from sfa.util.cache import Cache -from sfa.storage.persistentobjs import RegRecord, RegAuthority, RegUser, RegSlice, RegNode -from sfa.storage.persistentobjs import make_record +from sfa.storage.model import RegRecord, RegAuthority, RegUser, RegSlice, RegNode +from sfa.storage.model import make_record from sfa.rspecs.rspec import RSpec from sfa.rspecs.rspec_converter import RSpecConverter @@ -88,16 +89,28 @@ def filter_records(type, records): # save methods -def save_variable_to_file(var, filename, format="text"): - f = open(filename, "w") +def save_raw_to_file(var, filename, format="text", banner=None): + if filename == "-": + # if filename is "-", send it to stdout + f = sys.stdout + else: + f = open(filename, "w") + if banner: + f.write(banner+"\n") if format == "text": f.write(str(var)) elif format == "pickled": f.write(pickle.dumps(var)) + elif format == "json": + if hasattr(json, "dumps"): + f.write(json.dumps(var)) # python 2.6 + else: + f.write(json.write(var)) # python 2.5 else: # this should never happen print "unknown output format", format - + if banner: + f.write('\n'+banner+"\n") def save_rspec_to_file(rspec, filename): if not filename.endswith(".rspec"): @@ -289,13 +302,6 @@ class Sfi: help="output file format ([xml]|xmllist|hrnlist)", default="xml", choices=("xml", "xmllist", "hrnlist")) - if command in ("status", "version"): - parser.add_option("-o", "--output", dest="file", - help="output dictionary to file", metavar="FILE", default=None) - parser.add_option("-F", "--fileformat", dest="fileformat", type="choice", - help="output file format ([text]|pickled)", default="text", - choices=("text","pickled")) - if command in ("delegate"): parser.add_option("-u", "--user", action="store_true", dest="delegate_user", default=False, @@ -323,6 +329,13 @@ class Sfi: help="root registry", metavar="URL", default=None) parser.add_option("-s", "--sliceapi", dest="sm", default=None, metavar="URL", help="slice API - in general a SM URL, but can be used to talk to an aggregate") + parser.add_option("-R", "--raw", dest="raw", default=None, + help="Save raw, unparsed server response to a file") + parser.add_option("", "--rawformat", dest="rawformat", type="choice", + help="raw file format ([text]|pickled|json)", default="text", + choices=("text","pickled","json")) + parser.add_option("", "--rawbanner", dest="rawbanner", default=None, + help="text string to write before and after raw output") parser.add_option("-d", "--dir", dest="sfi_dir", help="config & working directory - default is %default", metavar="PATH", default=Sfi.default_sfi_dir()) @@ -642,17 +655,17 @@ class Sfi: else: self.logger.critical("No such registry record file %s"%record) sys.exit(1) - + #========================================================================== # Following functions implement the commands # # Registry-related commands #========================================================================== - + def version(self, options, args): """ - display an SFA server version (GetVersion) + display an SFA server version (GetVersion) or version information about sfi itself """ if options.version_local: @@ -664,10 +677,11 @@ or version information about sfi itself server = self.sliceapi() result = server.GetVersion() version = ReturnValue.get_value(result) - pprinter = PrettyPrinter(indent=4) - pprinter.pprint(version) - if options.file: - save_variable_to_file(version, options.file, options.fileformat) + if self.options.raw: + save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + else: + pprinter = PrettyPrinter(indent=4) + pprinter.pprint(version) def list(self, options, args): """ @@ -782,9 +796,12 @@ or version information about sfi itself api_options['call_id']=unique_call_id() result = server.ListSlices(creds, *self.ois(server,api_options)) value = ReturnValue.get_value(result) - display_list(value) + if self.options.raw: + save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + else: + display_list(value) return - + # show rspec for named slice def resources(self, options, args): """ @@ -801,9 +818,9 @@ or with an slice hrn, shows currently provisioned resources creds.append(self.my_credential_string) if options.delegate: creds.append(self.delegate_cred(cred, get_authority(self.authority))) - + # no need to check if server accepts the options argument since the options has - # been a required argument since v1 API + # been a required argument since v1 API api_options = {} # always send call_id to v2 servers api_options ['call_id'] = unique_call_id() @@ -826,15 +843,18 @@ or with an slice hrn, shows currently provisioned resources # just request the version the client wants api_options['geni_rspec_version'] = version_manager.get_version(options.rspec_version).to_dict() else: - api_options['geni_rspec_version'] = {'type': 'geni', 'version': '3.0'} + api_options['geni_rspec_version'] = {'type': 'geni', 'version': '3.0'} else: - api_options['geni_rspec_version'] = {'type': 'geni', 'version': '3.0'} + api_options['geni_rspec_version'] = {'type': 'geni', 'version': '3.0'} result = server.ListResources (creds, api_options) value = ReturnValue.get_value(result) - if options.file is None: - display_rspec(value, options.format) - else: + if self.options.raw: + save_raw_to_file(result, 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 def create(self, options, args): @@ -860,8 +880,8 @@ or with an slice hrn, shows currently provisioned resources # delegated_cred = self.delegate_cred(slice_cred, server_version['hrn']) #elif server_version.get('urn'): # delegated_cred = self.delegate_cred(slice_cred, urn_to_hrn(server_version['urn'])) - - # rspec + + # rspec rspec_file = self.get_rspec_file(args[1]) rspec = open(rspec_file).read() @@ -886,8 +906,8 @@ or with an slice hrn, shows currently provisioned resources rspec = RSpecConverter.to_pg_rspec(rspec.toxml(), content_type='request') else: users = sfa_users_arg(user_records, slice_record) - - # do not append users, keys, or slice tags. Anything + + # do not append users, keys, or slice tags. Anything # not contained in this request will be removed from the slice # CreateSliver has supported the options argument for a while now so it should @@ -898,10 +918,13 @@ or with an slice hrn, shows currently provisioned resources result = server.CreateSliver(slice_urn, creds, rspec, users, *self.ois(server, api_options)) value = ReturnValue.get_value(result) - if options.file is None: - print value - else: + if self.options.raw: + save_raw_to_file(result, 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): + print value + return value def delete(self, options, args): @@ -925,8 +948,12 @@ or with an slice hrn, shows currently provisioned resources api_options = {} api_options ['call_id'] = unique_call_id() result = server.DeleteSliver(slice_urn, creds, *self.ois(server, api_options ) ) - # xxx no ReturnValue ?? - return result + value = ReturnValue.get_value(result) + if self.options.raw: + save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + else: + print value + return value def status(self, options, args): """ @@ -947,12 +974,13 @@ or with an slice hrn, shows currently provisioned resources # options and call_id when supported api_options = {} - api_options['call_id']=unique_call_id() + api_options['call_id']=unique_call_id() result = server.SliverStatus(slice_urn, creds, *self.ois(server,api_options)) value = ReturnValue.get_value(result) - print value - if options.file: - save_variable_to_file(value, options.file, options.fileformat) + if self.options.raw: + save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + else: + print value def start(self, options, args): """ @@ -971,7 +999,13 @@ or with an slice hrn, shows currently provisioned resources delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority)) creds.append(delegated_cred) # xxx Thierry - does this not need an api_options as well ? - return server.Start(slice_urn, creds) + result = server.Start(slice_urn, creds) + value = ReturnValue.get_value(result) + if self.options.raw: + save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + else: + print value + return value def stop(self, options, args): """ @@ -987,7 +1021,13 @@ or with an slice hrn, shows currently provisioned resources if options.delegate: delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority)) creds.append(delegated_cred) - return server.Stop(slice_urn, creds) + result = server.Stop(slice_urn, creds) + value = ReturnValue.get_value(result) + if self.options.raw: + save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + else: + print value + return value # reset named slice def reset(self, options, args): @@ -1004,7 +1044,13 @@ or with an slice hrn, shows currently provisioned resources if options.delegate: delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority)) creds.append(delegated_cred) - return server.reset_slice(creds, slice_urn) + result = server.reset_slice(creds, slice_urn) + value = ReturnValue.get_value(result) + if self.options.raw: + save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + else: + print value + return value def renew(self, options, args): """ @@ -1027,6 +1073,10 @@ or with an slice hrn, shows currently provisioned resources api_options['call_id']=unique_call_id() result = server.RenewSliver(slice_urn, creds, 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) + else: + print value return value @@ -1044,7 +1094,13 @@ or with an slice hrn, shows currently provisioned resources if options.delegate: delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority)) creds.append(delegated_cred) - return server.Shutdown(slice_urn, creds) + result = server.Shutdown(slice_urn, creds) + value = ReturnValue.get_value(result) + if self.options.raw: + save_raw_to_file(result, self.options.raw, self.options.rawformat, self.options.rawbanner) + else: + print value + return value def get_ticket(self, options, args):