#
# sfi.py - basic SFA command-line client
-# the actual binary in sfa/clientbin essentially runs main()
-# this module is used in sfascan
+# this module is also used in sfascan
#
import sys
from StringIO import StringIO
from optparse import OptionParser
from pprint import PrettyPrinter
+from tempfile import mkstemp
from sfa.trust.certificate import Keypair, Certificate
from sfa.trust.gid import GID
from sfa.client.sfaserverproxy import SfaServerProxy, ServerException
from sfa.client.client_helper import pg_users_arg, sfa_users_arg
from sfa.client.return_value import ReturnValue
+from sfa.client.candidates import Candidates
CM_PORT=12346
return filtered_records
+def credential_printable (credential_string):
+ credential=Credential(string=credential_string)
+ result=""
+ result += credential.get_summary_tostring()
+ result += "\n"
+ rights = credential.get_privileges()
+ result += "rights=%s"%rights
+ result += "\n"
+ return result
+
+def show_credentials (cred_s):
+ if not isinstance (cred_s,list): cred_s = [cred_s]
+ for cred in cred_s:
+ print "Using Credential %s"%credential_printable(cred)
+
# save methods
def save_raw_to_file(var, filename, format="text", banner=None):
if filename == "-":
("get_ticket", "slice_hrn rspec"),
("redeem_ticket", "ticket"),
("delegate", "name"),
- ("create_gid", "[name]"),
- ("get_trusted_certs", "cred"),
+ ("gid", "[name]"),
+ ("trusted", "cred"),
("config", ""),
]
help="Include a credential delegated to the user's root"+\
"authority in set of credentials for this call")
+ # show_credential option
+ if command in ("list","resources","create","add","update","remove","slices","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
if command 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"):
+ parser.add_option("-k","--key",dest="keys",action="append",default=[],
+ help="specify specific keys to be displayed from record")
if command in ("resources"):
# rspec version
parser.add_option("-r", "--rspec-version", dest="rspec_version", default="SFA 1",
# a new option to retreive or not reservation-oriented RSpecs (leases)
parser.add_option("-l", "--list_leases", dest="list_leases", type="choice",
help="Retreive or not reservation-oriented RSpecs ([resources]|leases|all )",
+ choices=("all", "resources", "leases"), default="resources")
# 'create' does return the new rspec, makes sense to save that too
- if command in ("resources", "show", "list", "create_gid", 'create'):
+ if command in ("resources", "show", "list", "gid", 'create'):
parser.add_option("-o", "--output", dest="file",
help="output XML to file", metavar="FILE", default=None)
def print_help (self):
+ print "==================== Generic sfi usage"
self.sfi_parser.print_help()
+ print "==================== Specific command usage"
self.command_parser.print_help()
#
self.print_command_help(options)
return -1
- command = args[0]
+ # complete / find unique match with command set
+ command_candidates = Candidates (self.available_names)
+ input = args[0]
+ command = command_candidates.only_match(input)
+ if not command:
+ self.print_command_help(options)
+ sys.exit(1)
+ # second pass options parsing
self.command_parser = self.create_command_parser(command)
(command_options, command_args) = self.command_parser.parse_args(args[1:])
self.command_options = command_options
self.read_config ()
self.bootstrap ()
- self.logger.info("Command=%s" % command)
+ self.logger.debug("Command=%s" % command)
try:
self.dispatch(command, command_options, command_args)
except KeyError:
self.logger.critical ("Unknown command %s"%command)
- raise
sys.exit(1)
-
+
return
+ def upgrade_config(self, config_file):
+ """
+ upgrade from shell to ini format
+ """
+ fp, fn = mkstemp(suffix='sfi_config', text=True)
+ try:
+ tmp_config = Config(fn)
+ tmp_config.add_section('sfi')
+ tmp_config.add_section('sface')
+ tmp_config.load(config_file)
+ tmp_config.save(config_file)
+ except:
+ raise
+ finally:
+ os.unlink(fn)
+
+
####################
def read_config(self):
config_file = os.path.join(self.options.sfi_dir,"sfi_config")
try:
- config = Config (config_file)
+ if Config.is_ini(config_file):
+ config = Config (config_file)
+ else:
+ # try upgrading from shell config format
+ self.upgrade_config(config_file)
+ config = Config(config_file)
+
except:
- self.logger.critical("Failed to read configuration file %s"%config_file)
- self.logger.info("Make sure to remove the export clauses and to add quotes")
- if self.options.verbose==0:
- self.logger.info("Re-run with -v for more details")
- else:
- self.logger.log_exc("Could not read config file %s"%config_file)
- sys.exit(1)
+ self.logger.critical("Failed to read configuration file %s"%config_file)
+ self.logger.info("Make sure to remove the export clauses and to add quotes")
+ if self.options.verbose==0:
+ self.logger.info("Re-run with -v for more details")
+ else:
+ self.logger.log_exc("Could not read config file %s"%config_file)
+ sys.exit(1)
errors = 0
# Set SliceMgr URL
elif hasattr(config, "SFI_REGISTRY"):
self.reg_url = config.SFI_REGISTRY
else:
- self.logger.errors("You need to set e.g. SFI_REGISTRY='http://your.registry.url:12345/' in %s" % config_file)
+ self.logger.error("You need to set e.g. SFI_REGISTRY='http://your.registry.url:12345/' in %s" % config_file)
errors += 1
# Set user HRN
elif hasattr(config, "SFI_USER"):
self.user = config.SFI_USER
else:
- self.logger.errors("You need to set e.g. SFI_USER='plc.princeton.username' in %s" % config_file)
+ self.logger.error("You need to set e.g. SFI_USER='plc.princeton.username' in %s" % config_file)
errors += 1
# Set authority HRN
# init self-signed cert, user credentials and gid
def bootstrap (self):
- client_bootstrap = SfaClientBootstrap (self.user, self.reg_url, self.options.sfi_dir)
+ 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
if self.options.user_private_key:
client_bootstrap.init_private_key_if_missing (self.options.user_private_key)
if options.recursive:
opts['recursive'] = options.recursive
+ if options.show_credential:
+ show_credentials(self.my_credential_string)
try:
list = self.registry().List(hrn, self.my_credential_string, options)
except IndexError:
record_dicts = filter_records(options.type, record_dicts)
if not record_dicts:
self.logger.error("No record of type %s"% options.type)
+ return
+ # user has required to focus on some keys
+ if options.keys:
+ def project (record):
+ projected={}
+ for key in options.keys:
+ try: projected[key]=record[key]
+ except: pass
+ return projected
+ record_dicts = [ project (record) for record in record_dicts ]
records = [ Record(dict=record_dict) for record_dict in record_dicts ]
for record in records:
if (options.format == "text"): record.dump(sort=True)
def add(self, options, args):
"add record into registry from xml file (Register)"
auth_cred = self.my_authority_credential_string()
+ if options.show_credential:
+ show_credentials(auth_cred)
record_dict = {}
if len(args) > 0:
record_filepath = args[0]
cred = self.my_authority_credential_string()
elif record_dict['type'] in ["slice"]:
try:
- cred = self.slice_credential_string(record.hrn)
+ cred = self.slice_credential_string(record_dict['hrn'])
except ServerException, e:
# XXX smbaker -- once we have better error return codes, update this
# to do something better than a string compare
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)
def remove(self, options, args):
type = options.type
if type in ['all']:
type = '*'
+ if options.show_credential:
+ show_credentials(auth_cred)
return self.registry().Remove(hrn, auth_cred, type)
# ==================================================================
# options and call_id when supported
api_options = {}
api_options['call_id']=unique_call_id()
+ if options.show_credential:
+ show_credentials(creds)
result = server.ListSlices(creds, *self.ois(server,api_options))
value = ReturnValue.get_value(result)
if self.options.raw:
creds.append(self.my_credential_string)
if options.delegate:
creds.append(self.delegate_cred(cred, get_authority(self.authority)))
+ if options.show_credential:
+ show_credentials(creds)
# no need to check if server accepts the options argument since the options has
# been a required argument since v1 API
# credentials
creds = [self.slice_credential_string(slice_hrn)]
+
delegated_cred = None
server_version = self.get_cached_server_version(server)
if server_version.get('interface') == 'slicemgr':
#elif server_version.get('urn'):
# delegated_cred = self.delegate_cred(slice_cred, urn_to_hrn(server_version['urn']))
+ if options.show_credential:
+ show_credentials(creds)
+
# rspec
rspec_file = self.get_rspec_file(args[1])
rspec = open(rspec_file).read()
# options and call_id when supported
api_options = {}
api_options ['call_id'] = unique_call_id()
+ if options.show_credential:
+ show_credentials(creds)
result = server.DeleteSliver(slice_urn, creds, *self.ois(server, api_options ) )
value = ReturnValue.get_value(result)
if self.options.raw:
# options and call_id when supported
api_options = {}
api_options['call_id']=unique_call_id()
+ if options.show_credential:
+ show_credentials(creds)
result = server.SliverStatus(slice_urn, creds, *self.ois(server,api_options))
value = ReturnValue.get_value(result)
if self.options.raw:
renew slice (RenewSliver)
"""
server = self.sliceapi()
+ if len(args) != 2:
+ self.print_help()
+ sys.exit(1)
+ [ slice_hrn, input_time ] = args
# slice urn
- slice_hrn = args[0]
slice_urn = hrn_to_urn(slice_hrn, 'slice')
+ # time: don't try to be smart on the time format, server-side will
# creds
slice_cred = self.slice_credential_string(args[0])
creds = [slice_cred]
if options.delegate:
delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
creds.append(delegated_cred)
- # time
- time = args[1]
# options and call_id when supported
api_options = {}
api_options['call_id']=unique_call_id()
- result = server.RenewSliver(slice_urn, creds, time, *self.ois(server,api_options))
+ if options.show_credential:
+ show_credentials(creds)
+ result = server.RenewSliver(slice_urn, 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)
self.logger.log_exc(e.message)
return
- def create_gid(self, options, args):
+ def gid(self, options, args):
"""
Create a GID (CreateGid)
"""
self.logger.info("delegated credential for %s to %s and wrote to %s"%(object_hrn, delegee_hrn,dest_fn))
- def get_trusted_certs(self, options, args):
+ def trusted(self, options, args):
"""
return uhe trusted certs at this interface (get_trusted_certs)
"""
gid = GID(string=trusted_cert)
gid.dump()
cert = Certificate(string=trusted_cert)
- self.logger.debug('Sfi.get_trusted_certs -> %r'%cert.get_subject())
+ self.logger.debug('Sfi.trusted -> %r'%cert.get_subject())
return
def config (self, options, args):