X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fclient%2Fsfi.py;h=a8d96d66823d5bcf1b9652e9ae11ee86807cf7b8;hb=f8368a35b82bb1f6f818929b75192206c55f1db7;hp=84c77d6806529a2ca980761d7040ade615f2fb4b;hpb=40d980701a909581b485fbcf7c58ca3ace543961;p=sfa.git diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py index 84c77d68..a8d96d66 100755 --- a/sfa/client/sfi.py +++ b/sfa/client/sfi.py @@ -10,13 +10,12 @@ import traceback import socket import random import datetime +import zlib from lxml import etree from StringIO import StringIO from types import StringTypes, ListType from optparse import OptionParser -import zlib - -from sfa.util.sfalogging import sfa_logger,sfa_logger_goes_to_console +from sfa.util.sfalogging import _SfaLogger, logging from sfa.trust.certificate import Keypair, Certificate from sfa.trust.gid import GID from sfa.trust.credential import Credential @@ -26,6 +25,7 @@ from sfa.util.xrn import Xrn, get_leaf, get_authority, hrn_to_urn import sfa.util.xmlrpcprotocol as xmlrpcprotocol from sfa.util.config import Config from sfa.util.version import version_core +from sfa.util.cache import Cache AGGREGATE_PORT=12346 CM_PORT=12346 @@ -134,14 +134,16 @@ class Sfi: for opt in Sfi.required_options: if not hasattr(options,opt): setattr(options,opt,None) if not hasattr(options,'sfi_dir'): options.sfi_dir=os.path.expanduser("~/.sfi/") + self.sfi_dir = options.sfi_dir self.options = options self.slicemgr = None self.registry = None self.user = None self.authority = None self.hashrequest = False - sfa_logger_goes_to_console() - self.logger=sfa_logger() + #sfa_logger_goes_to_console() + #self.logger=sfa_logger() + self.logger = _SfaLogger(self.sfi_dir + 'sfi.log', level = logging.INFO) def create_cmd_parser(self, command, additional_cmdargs=None): cmdargs = {"list": "authority", @@ -209,6 +211,10 @@ class Sfi: parser.add_option("-f", "--format", dest="format", type="choice", help="display format ([xml]|dns|ip)", default="xml", choices=("xml", "dns", "ip")) + #panos: a new option to define the type of information about resources a user is interested in + parser.add_option("-i", "--info", dest="info", + help="optional component information", default=None) + if command in ("resources", "show", "list"): parser.add_option("-o", "--output", dest="file", @@ -272,7 +278,7 @@ class Sfi: return parser - + def read_config(self): config_file = self.options.sfi_dir + os.sep + "sfi_config" try: @@ -340,15 +346,54 @@ class Sfi: self.key = Keypair(filename=key_file) self.key_file = key_file self.cert_file = cert_file - self.cert = GID(filename=cert_file) - # Establish connection to server(s) + self.cert = GID(filename=cert_file) self.logger.info("Contacting Registry at: %s"%self.reg_url) self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, self.options) self.logger.info("Contacting Slice Manager at: %s"%self.sm_url) self.slicemgr = xmlrpcprotocol.get_server(self.sm_url, key_file, cert_file, self.options) - return - + + def get_cached_server_version(self, server): + # check local cache first + cache = None + version = None + cache_file = self.sfi_dir + os.path.sep + 'sfi_cache.dat' + cache_key = server.url + "-version" + try: + cache = Cache(cache_file) + except IOError: + cache = Cache() + self.logger.info("Local cache not found at: %s" % cache_file) + + if cache: + version = cache.get(cache_key) + + if not version: + version = server.GetVersion() + # cache version for 24 hours + cache.add(cache_key, version, ttl= 60*60*24) + + + return version + + + def server_supports_call_id_arg(self, server): + """ + Returns true if server support the optional call_id arg, false otherwise. + """ + server_version = self.get_cached_server_version(server) + if 'sfa' in server_version: + code_tag = server_version['code_tag'] + code_tag_parts = code_tag.split("-") + + version_parts = code_tag_parts[0].split(".") + major, minor = version_parts[0], version_parts[1] + rev = code_tag_parts[1] + if int(major) > 1: + if int(minor) > 0 or int(rev) > 20: + return True + return False + # # Get various credential and spec files # @@ -389,10 +434,13 @@ class Sfi: cert.set_issuer(k, self.user) cert.sign() self.logger.info("Writing self-signed certificate to %s"%cert_file) + print "Writing self-signed certificate to %s"%cert_file cert.save_to_file(cert_file) + self.cert = cert # try to get registry issued cert try: self.logger.info("Getting Registry issued cert") + print "Getting Registry issued cert" self.read_config() # *hack. need to set registyr before _get_gid() is called self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, self.options) @@ -401,8 +449,10 @@ class Sfi: self.logger.info("Writing certificate to %s"%cert_file) gid.save_to_file(cert_file) except: + + print "Failed to download Registry issued cert" self.logger.info("Failed to download Registry issued cert") - + return cert_file def get_cached_gid(self, file): @@ -439,14 +489,18 @@ class Sfi: if not gid: user_cred = self.get_user_cred() records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True)) - record = None + if not records: + raise RecordNotFound(args[0]) + record = records[0] if type: + record=None for rec in records: - if type == record['type']: + if type == rec['type']: record = rec if not record: raise RecordNotFound(args[0]) - gid = GID(string=records[0]['gid']) + + gid = GID(string=record['gid']) self.logger.info("Writing gid to %s"%gidfile) gid.save_to_file(filename=gidfile) return gid @@ -632,7 +686,7 @@ class Sfi: record = SliceRecord(dict=record) elif record['type'] in ['node']: record = NodeRecord(dict=record) - elif record['type'] in ['authority', 'ma', 'sa']: + elif record['type'].startswith('authority'): record = AuthorityRecord(dict=record) else: record = SfaRecord(dict=record) @@ -640,7 +694,7 @@ class Sfi: record.dump() else: print record.save_to_string() - + if opts.file: file = opts.file if not file.startswith(os.sep): @@ -791,7 +845,6 @@ class Sfi: # ================================================================== # Slice-related commands # ================================================================== - def version(self, opts, args): if opts.version_local: @@ -831,7 +884,7 @@ class Sfi: if args: cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True) hrn = args[0] - call_options = {'geni_slice_urn': hrn_to_urn(hrn, 'slice')} + call_options = {'geni_slice_urn': hrn_to_urn(hrn, 'slice')} else: cred = user_cred hrn = None @@ -842,7 +895,14 @@ class Sfi: creds.append(delegated_cred) if opts.rspec_version: call_options['rspec_version'] = opts.rspec_version - result = server.ListResources(creds, call_options,unique_call_id()) + #panos add info options + if opts.info: + call_options['info'] = opts.info + + call_args = [creds, call_options] + if self.server_supports_call_id_arg(server): + call_args.append(unique_call_id()) + result = server.ListResources(*call_args) format = opts.format if opts.file is None: display_rspec(result, format) @@ -875,8 +935,9 @@ class Sfi: version = server.GetVersion() if 'sfa' not in version: # need to pass along user keys if this request is going to a ProtoGENI aggregate - # ProtoGeni Aggregaes will only install the keys of the user that is issuing the - # request. all slice keys + # ProtoGeni Aggregates will only install the keys of the user that is issuing the + # request. So we will only pass in one user that contains the keys for all + # users of the slice user = {'urn': user_cred.get_gid_caller().get_urn(), 'keys': []} slice_record = self.registry.Resolve(slice_urn, creds) @@ -887,8 +948,13 @@ class Sfi: for user_record in user_records: if 'keys' in user_record: user['keys'].extend(user_record['keys']) - users.append(user) - result = server.CreateSliver(slice_urn, creds, rspec, users, unique_call_id()) + users.append(user) + + call_args = [slice_urn, creds, rspec, users] + if self.server_supports_call_id_arg(server): + call_args.append(unique_call_id()) + + result = server.CreateSliver(*call_args) print result return result @@ -955,8 +1021,12 @@ class Sfi: delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority)) creds.append(delegated_cred) server = self.get_server_from_opts(opts) - return server.DeleteSliver(slice_urn, creds, unique_call_id()) - + + call_args = [slice_urn, creds] + if self.server_supports_call_id_arg(server): + call_args.append(unique_call_id()) + return server.DeleteSliver(*call_args) + # start named slice def start(self, opts, args): slice_hrn = args[0] @@ -1003,7 +1073,11 @@ class Sfi: delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority)) creds.append(delegated_cred) time = args[1] - return server.RenewSliver(slice_urn, creds, time, unique_call_id()) + + call_args = [slice_urn, creds, time] + if self.server_supports_call_id_arg(server): + call_args.append(unique_call_id()) + return server.RenewSliver(*call_args) def status(self, opts, args): @@ -1015,7 +1089,10 @@ class Sfi: delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority)) creds.append(delegated_cred) server = self.get_server_from_opts(opts) - print server.SliverStatus(slice_urn, creds, unique_call_id()) + call_args = [slice_urn, creds] + if self.server_supports_call_id_arg(server): + call_args.append(unique_call_id()) + print server.SliverStatus(*call_args) def shutdown(self, opts, args): @@ -1054,7 +1131,6 @@ class Sfi: (cmd_opts, cmd_args) = self.cmd_parser.parse_args(args[1:]) self.set_servers() - self.logger.info("Command=%s" % command) if command in ("resources"): self.logger.debug("resources cmd_opts %s" % cmd_opts.format)