X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fclient%2Fsfi.py;h=179e137331ffc1e9f7daaede019a78a13a5a8641;hb=75dfdfc317c8557904cfd192979182f1591595e3;hp=3188e9ad421776f965e2a426fa3f72dc97f67ee1;hpb=bb08c68eb53c55009be93fd91579a9685eb23860;p=sfa.git diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py index 3188e9ad..179e1373 100755 --- a/sfa/client/sfi.py +++ b/sfa/client/sfi.py @@ -13,10 +13,9 @@ from sfa.trust.certificate import Keypair, Certificate from sfa.trust.credential import Credential from sfa.util.geniclient import GeniClient from sfa.util.record import * -from sfa.util.rspec import Rspec +from sfa.util.rspec import RSpec from sfa.util.xmlrpcprotocol import ServerException import sfa.util.xmlrpcprotocol as xmlrpcprotocol -import sfa.util.soapprotocol as soapprotocol from sfa.util.config import Config class Sfi: @@ -26,7 +25,107 @@ class Sfi: user = None authority = None options = None - + hashrequest = False + + def create_cmd_parser(self,command, additional_cmdargs = None): + cmdargs = {"gid": "", + "list": "name", + "show": "name", + "remove": "name", + "add": "record", + "update": "record", + "aggregates": "[name]", + "registries": "[name]", + "slices": "", + "resources": "[name]", + "create": "name rspec", + "delete": "name", + "reset": "name", + "start": "name", + "stop": "name", + "delegate": "name" + } + + if additional_cmdargs: + cmdargs.update(additional_cmdargs) + + if command not in cmdargs: + print "Invalid command\n" + print "Commands: ", + for key in cmdargs.keys(): + print key+",", + print "" + sys.exit(2) + + parser = OptionParser(usage="sfi [sfi_options] %s [options] %s" \ + % (command, cmdargs[command])) + + if command in ("resources"): + parser.add_option("-f", "--format", dest="format",type="choice", + help="display format ([xml]|dns|ip)",default="xml", + choices=("xml","dns","ip")) + parser.add_option("-a", "--aggregate", dest="aggregate", + default=None, help="aggregate hrn") + + if command in ("create"): + parser.add_option("-a", "--aggregate", dest="aggregate",default=None, + help="aggregate hrn") + + if command in ("list", "show", "remove"): + parser.add_option("-t", "--type", dest="type",type="choice", + help="type filter ([all]|user|slice|sa|ma|node|aggregate)", + choices=("all","user","slice","sa","ma","node","aggregate"), + default="all") + + if command in ("resources", "show", "list"): + parser.add_option("-o", "--output", dest="file", + help="output XML to file", metavar="FILE", default=None) + + if command in ("show", "list"): + parser.add_option("-f", "--format", dest="format", type="choice", + help="display format ([text]|xml)",default="text", + choices=("text","xml")) + + if command in ("delegate"): + parser.add_option("-u", "--user", + action="store_true", dest="delegate_user", default=False, + help="delegate user credential") + parser.add_option("-s", "--slice", dest="delegate_slice", + help="delegate slice credential", metavar="HRN", default=None) + return parser + + + def create_parser(self): + + # Generate command line parser + parser = OptionParser(usage="sfi [options] command [command_options] [command_args]", + description="Commands: gid,list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset") + parser.add_option("-r", "--registry", dest="registry", + help="root registry", metavar="URL", default=None) + parser.add_option("-s", "--slicemgr", dest="sm", + help="slice manager", metavar="URL", default=None) + default_sfi_dir=os.path.expanduser("~/.sfi/") + parser.add_option("-d", "--dir", dest="sfi_dir", + help="config & working directory - default is " + default_sfi_dir, + metavar="PATH", default = default_sfi_dir) + parser.add_option("-u", "--user", dest="user", + help="user name", metavar="HRN", default=None) + parser.add_option("-a", "--auth", dest="auth", + help="authority name", metavar="HRN", default=None) + parser.add_option("-v", "--verbose", + action="store_true", dest="verbose", default=False, + help="verbose mode") + parser.add_option("-p", "--protocol", + dest="protocol", default="xmlrpc", + help="RPC protocol (xmlrpc or soap)") + parser.add_option("-h", "--hashrequest", + action="store_true", dest="hashrequest", default=False, + help="Create a hash of the request that will be authenticated on the server") + parser.disable_interspersed_args() + + return parser + + # # Establish Connection to SliceMgr and Registry Servers # @@ -95,9 +194,10 @@ class Sfi: self.cert_file = cert_file self.cert = Certificate(filename=cert_file) # Establish connection to server(s) - self.slicemgr = GeniClient(sm_url, key_file, cert_file, self.options.protocol) + #self.slicemgr = GeniClient(sm_url, key_file, cert_file, self.options.protocol) #self.registry = GeniClient(reg_url, key_file, cert_file, self.options.protocol) self.registry = xmlrpcprotocol.get_server(reg_url, key_file, cert_file) + self.slicemgr = xmlrpcprotocol.get_server(sm_url, key_file, cert_file) return # @@ -158,23 +258,24 @@ class Sfi: return gid def get_user_cred(self): - file = os.path.join(self.options.sfi_dir, self.get_leaf(self.user) + ".cred") - if (os.path.isfile(file)): - user_cred = Credential(filename=file) - return user_cred - else: - # bootstrap user credential - request_hash = self.key.compute_hash([None, "user", self.user]) - user_cred = self.registry.get_credential(None, "user", self.user, request_hash) - if user_cred: - cred = Credential(string=user_cred) - cred.save_to_file(file, save_parents=True) - if self.options.verbose: - print "Writing user credential to", file - return cred - else: - print "Failed to get user credential" - sys.exit(-1) + file = os.path.join(self.options.sfi_dir, self.get_leaf(self.user) + ".cred") + if (os.path.isfile(file)): + user_cred = Credential(filename=file) + return user_cred + else: + # bootstrap user credential + cert_string = self.cert.save_to_string(save_parents=True) + request_hash = self.key.compute_hash([cert_string, "user", self.user]) + user_cred = self.registry.get_self_credential(cert_string, "user", self.user, request_hash) + if user_cred: + cred = Credential(string=user_cred) + cred.save_to_file(file, save_parents=True) + if self.options.verbose: + print "Writing user credential to", file + return cred + else: + print "Failed to get user credential" + sys.exit(-1) def get_auth_cred(self): @@ -208,9 +309,12 @@ class Sfi: return slice_cred else: # bootstrap slice credential from user credential - user_cred = self.get_user_cred() - slice_cred = self.registry.get_credential(user_cred, "slice", name) - if slice_cred: + user_cred = self.get_user_cred().save_to_string(save_parents=True) + arg_list = [user_cred, "slice", name] + request_hash = self.key.compute_hash(arg_list) + slice_cred_str = self.registry.get_credential(user_cred, "slice", name, request_hash) + if slice_cred_str: + slice_cred = Credential(string=slice_cred_str) slice_cred.save_to_file(file, save_parents=True) if self.options.verbose: print "Writing slice credential to", file @@ -291,164 +395,68 @@ class Sfi: os.remove(outfn) return key_string - # - # Generate sub-command parser - # - def create_cmd_parser(self,command, additional_cmdargs = None): - cmdargs = {"gid": "", - "list": "name", - "show": "name", - "remove": "name", - "add": "record", - "update": "record", - "aggregates": "[name]", - "registries": "[name]", - "slices": "", - "resources": "[name]", - "create": "name rspec", - "delete": "name", - "reset": "name", - "start": "name", - "stop": "name", - "delegate": "name" - } - - if additional_cmdargs: - cmdargs.update(additional_cmdargs) - - if command not in cmdargs: - print "Invalid command\n" - print "Commands: ", - for key in cmdargs.keys(): - print key+",", - print "" - sys.exit(2) - - parser = OptionParser(usage="sfi [sfi_options] %s [options] %s" \ - % (command, cmdargs[command])) - - if command in ("resources"): - parser.add_option("-f", "--format", dest="format",type="choice", - help="display format ([xml]|dns|ip)",default="xml", - choices=("xml","dns","ip")) - parser.add_option("-a", "--aggregate", dest="aggregate", - default=None, help="aggregate hrn") - - if command in ("create"): - parser.add_option("-a", "--aggregate", dest="aggregate",default=None, - help="aggregate hrn") - - if command in ("list", "show", "remove"): - parser.add_option("-t", "--type", dest="type",type="choice", - help="type filter ([all]|user|slice|sa|ma|node|aggregate)", - choices=("all","user","slice","sa","ma","node","aggregate"), - default="all") - - if command in ("resources", "show", "list"): - parser.add_option("-o", "--output", dest="file", - help="output XML to file", metavar="FILE", default=None) - - if command in ("show", "list"): - parser.add_option("-f", "--format", dest="format", type="choice", - help="display format ([text]|xml)",default="text", - choices=("text","xml")) - - if command in ("delegate"): - parser.add_option("-u", "--user", - action="store_true", dest="delegate_user", default=False, - help="delegate user credential") - parser.add_option("-s", "--slice", dest="delegate_slice", - help="delegate slice credential", metavar="HRN", default=None) - return parser - - def create_parser(self): - - # Generate command line parser - parser = OptionParser(usage="sfi [options] command [command_options] [command_args]", - description="Commands: gid,list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset") - parser.add_option("-r", "--registry", dest="registry", - help="root registry", metavar="URL", default=None) - parser.add_option("-s", "--slicemgr", dest="sm", - help="slice manager", metavar="URL", default=None) - default_sfi_dir=os.path.expanduser("~/.sfi/") - parser.add_option("-d", "--dir", dest="sfi_dir", - help="config & working directory - default is " + default_sfi_dir, - metavar="PATH", default = default_sfi_dir) - parser.add_option("-u", "--user", dest="user", - help="user name", metavar="HRN", default=None) - parser.add_option("-a", "--auth", dest="auth", - help="authority name", metavar="HRN", default=None) - parser.add_option("-v", "--verbose", - action="store_true", dest="verbose", default=False, - help="verbose mode") - parser.add_option("-p", "--protocol", - dest="protocol", default="xmlrpc", - help="RPC protocol (xmlrpc or soap)") - parser.disable_interspersed_args() - - return parser - - def dispatch(self,command, cmd_opts, cmd_args): - getattr(self,command)(cmd_opts, cmd_args) # # Following functions implement the commands # # Registry-related commands # - + + def dispatch(self,command, cmd_opts, cmd_args): + getattr(self,command)(cmd_opts, cmd_args) + def gid(self, opts, args): - gid = self.get_gid() - print "GID: %s" % (gid.save_to_string(save_parents=True)) - return + gid = self.get_gid() + print "GID: %s" % (gid.save_to_string(save_parents=True)) + return # list entires in named authority registry def list(self,opts, args): - user_cred = self.get_user_cred().save_to_string(save_parents=True) - hrn = args[0] - request_hash = self.key.compute_hash([user_cred, hrn]) - try: - list = self.registry.list(user_cred, hrn, request_hash) - except IndexError: - raise Exception, "Not enough parameters for the 'list' command" + user_cred = self.get_user_cred().save_to_string(save_parents=True) + hrn = args[0] + request_hash = self.key.compute_hash([user_cred, hrn]) + try: + list = self.registry.list(user_cred, hrn, request_hash) + except IndexError: + raise Exception, "Not enough parameters for the 'list' command" - # filter on person, slice, site, node, etc. - # THis really should be in the self.filter_records funct def comment... - list = self.filter_records(opts.type, list) - for record in list: - print "%s (%s)" % (record['hrn'], record['type']) - if opts.file: - self.save_records_to_file(opts.file, list) - return + # filter on person, slice, site, node, etc. + # THis really should be in the self.filter_records funct def comment... + list = self.filter_records(opts.type, list) + for record in list: + print "%s (%s)" % (record['hrn'], record['type']) + if opts.file: + self.save_records_to_file(opts.file, list) + return # show named registry record def show(self,opts, args): - user_cred = self.get_user_cred().save_to_string(save_parents=True) - hrn = args[0] - request_hash = self.key.compute_hash([user_cred, hrn]) - records = self.registry.resolve(user_cred, hrn, request_hash) - records = self.filter_records(opts.type, records) - if not records: - print "No record of type", opts.type - for record in records: - if record['type'] in ['user']: - record = UserRecord(dict = record) - elif record['type'] in ['slice']: - record = SliceRecord(dict = record) - elif record['type'] in ['node']: - record = NodeRecord(dict = record) - elif record['type'] in ['authority', 'ma', 'sa']: - record = AuthorityRecord(dict = record) - else: - record = GeniRecord(dict = record) - if (opts.format=="text"): - record.dump() - else: - print record.save_to_string() + user_cred = self.get_user_cred().save_to_string(save_parents=True) + hrn = args[0] + request_hash = self.key.compute_hash([user_cred, hrn]) + records = self.registry.resolve(user_cred, hrn, request_hash) + records = self.filter_records(opts.type, records) + if not records: + print "No record of type", opts.type + for record in records: + if record['type'] in ['user']: + record = UserRecord(dict = record) + elif record['type'] in ['slice']: + record = SliceRecord(dict = record) + elif record['type'] in ['node']: + record = NodeRecord(dict = record) + elif record['type'] in ['authority', 'ma', 'sa']: + record = AuthorityRecord(dict = record) + else: + record = GeniRecord(dict = record) + if (opts.format=="text"): + record.dump() + else: + print record.save_to_string() - if opts.file: - self.save_records_to_file(opts.file, records) - return + if opts.file: + self.save_records_to_file(opts.file, records) + return def delegate(self,opts, args): user_cred = self.get_user_cred() @@ -687,7 +695,7 @@ class Sfi: def display_rspec(self,rspec, format = 'rspec'): if format in ['dns']: - spec = Rspec() + spec = RSpec() spec.parseString(rspec) hostnames = [] nodespecs = spec.getDictsByTagName('NodeSpec') @@ -699,7 +707,7 @@ class Sfi: hostnames.append(nodespec['name']) result = hostnames elif format in ['ip']: - spec = Rspec() + spec = RSpec() spec.parseString(rspec) ips = [] ifspecs = spec.getDictsByTagName('IfSpec') @@ -783,39 +791,40 @@ class Sfi: # Main: parse arguments and dispatch to command # def main(self): - parser = self.create_parser() - (options, args) = parser.parse_args() - self.options = options - - if len(args) <= 0: + parser = self.create_parser() + (options, args) = parser.parse_args() + self.options = options + + if options.hashrequest: + self.hashrequest=True + + if len(args) <= 0: print "No command given. Use -h for help." return -1 - command = args[0] - (cmd_opts, cmd_args) = self.create_cmd_parser(command).parse_args(args[1:]) - if self.options.verbose : - print "Registry %s, sm %s, dir %s, user %s, auth %s" % (options.registry, - options.sm, - options.sfi_dir, - options.user, + command = args[0] + (cmd_opts, cmd_args) = self.create_cmd_parser(command).parse_args(args[1:]) + if self.options.verbose : + print "Registry %s, sm %s, dir %s, user %s, auth %s" % (options.registry, options.sm, + options.sfi_dir, options.user, options.auth) - print "Command %s" %command - if command in ("resources"): - print "resources cmd_opts %s" %cmd_opts.format - elif command in ("list","show","remove"): - print "cmd_opts.type %s" %cmd_opts.type - print "cmd_args %s" %cmd_args - - self.set_servers() - - try: - self.dispatch(command, cmd_opts, cmd_args) - except KeyError: - raise - print "Command not found:", command - sys.exit(1) + print "Command %s" %command + if command in ("resources"): + print "resources cmd_opts %s" %cmd_opts.format + elif command in ("list","show","remove"): + print "cmd_opts.type %s" %cmd_opts.type + print "cmd_args %s" %cmd_args + + self.set_servers() + + try: + self.dispatch(command, cmd_opts, cmd_args) + except KeyError: + raise + print "Command not found:", command + sys.exit(1) - return + return if __name__=="__main__": Sfi().main()