def call(self, ctxt, method, **kwargs): """Invoke a method and wait for a reply. See RPCClient.call().""" if self.target.fanout: raise exceptions.InvalidTarget("A call cannot be used with fanout", self.target) msg = self._make_message(ctxt, method, kwargs) msg_ctxt = self.serializer.serialize_context(ctxt) span_host = tomograph.getHost() ser_name = "%s[%s]" % ("RPC_call", self.target.topic) tomograph.start(ser_name, self.target.topic, span_host, 0) trace_info = tomograph.get_trace_info() msg_ctxt["trace_id"] = trace_info[0] msg_ctxt["span_id"] = trace_info[1] timeout = self.timeout if self.timeout is None: timeout = self.conf.rpc_response_timeout if self.version_cap: self._check_version_cap(msg.get("version")) try: result = self.transport._send( self.target, msg_ctxt, msg, wait_for_reply=True, timeout=timeout, retry=self.retry ) tomograph.stop(self.target.topic) except driver_base.TransportDriverError as ex: raise ClientSendError(self.target, ex) return self.serializer.deserialize_entity(ctxt, result)
def call(self, ctxt, method, **kwargs): """Invoke a method and wait for a reply. See RPCClient.call().""" if self.target.fanout: raise exceptions.InvalidTarget('A call cannot be used with fanout', self.target) msg = self._make_message(ctxt, method, kwargs) msg_ctxt = self.serializer.serialize_context(ctxt) span_host = tomograph.getHost() ser_name = "%s[%s]" % ("RPC_call", self.target.topic) tomograph.start(ser_name, self.target.topic, span_host, 0) trace_info = tomograph.get_trace_info() msg_ctxt["trace_id"] = trace_info[0] msg_ctxt["span_id"] = trace_info[1] timeout = self.timeout if self.timeout is None: timeout = self.conf.rpc_response_timeout if self.version_cap: self._check_version_cap(msg.get('version')) try: result = self.transport._send(self.target, msg_ctxt, msg, wait_for_reply=True, timeout=timeout, retry=self.retry) tomograph.stop(self.target.topic) except driver_base.TransportDriverError as ex: raise ClientSendError(self.target, ex) return self.serializer.deserialize_entity(ctxt, result)
def dec(request, *args, **kwargs): if dashboard: request.horizon['dashboard'] = dashboard if panel: request.horizon['panel'] = panel if not tomograph.tracing_started(): span_host = tomograph.getHost() ser_name = "%s[%s]" % (view_func.__module__, view_func.__name__) tomograph.start(ser_name, view_func.__name__, span_host, 0) ret = view_func(request, *args, **kwargs) tomograph.stop(view_func.__name__) return ret return view_func(request, *args, **kwargs)
def inner(*args, **kwargs): try: span_host = tomograph.getHost() ser_name = "%s[%s]" % (func.__module__, func.__name__) tomograph.start(ser_name, func.__name__, span_host, 0) ret = func(*args, **kwargs) tomograph.stop(func.__name__) return ret # Take advantage of the fact that we can catch # multiple exception types using a tuple of # exception classes, with subclass detection # for free. Any exception that is not in or # derived from the args passed to us will be # ignored and thrown as normal. except exceptions: tomograph.stop(func.__name__) raise rpc_dispatcher.ExpectedException()
def cast(self, ctxt, method, **kwargs): """Invoke a method and return immediately. See RPCClient.cast().""" msg = self._make_message(ctxt, method, kwargs) msg_ctxt = self.serializer.serialize_context(ctxt) span_host = tomograph.getHost() ser_name = "%s[%s]" % ("RPC_cast", self.target.topic) tomograph.start(ser_name, self.target.topic, span_host, 0) trace_info = tomograph.get_trace_info() msg_ctxt["trace_id"] = trace_info[0] msg_ctxt["span_id"] = trace_info[1] if self.version_cap: self._check_version_cap(msg.get("version")) try: self.transport._send(self.target, msg_ctxt, msg, retry=self.retry) tomograph.stop(self.target.topic) except driver_base.TransportDriverError as ex: raise ClientSendError(self.target, ex)
def cast(self, ctxt, method, **kwargs): """Invoke a method and return immediately. See RPCClient.cast().""" msg = self._make_message(ctxt, method, kwargs) msg_ctxt = self.serializer.serialize_context(ctxt) span_host = tomograph.getHost() ser_name = "%s[%s]" % ("RPC_cast", self.target.topic) tomograph.start(ser_name, self.target.topic, span_host, 0) trace_info = tomograph.get_trace_info() msg_ctxt["trace_id"] = trace_info[0] msg_ctxt["span_id"] = trace_info[1] if self.version_cap: self._check_version_cap(msg.get('version')) try: self.transport._send(self.target, msg_ctxt, msg, retry=self.retry) tomograph.stop(self.target.topic) except driver_base.TransportDriverError as ex: raise ClientSendError(self.target, ex)
def _do_dispatch(self, endpoint, method, ctxt, args, executor_callback): #pdb.set_trace() trace_info = None if ctxt.__contains__("trace_id"): trace_info = ctxt.pop("trace_id"), ctxt.pop("span_id") ctxt = self.serializer.deserialize_context(ctxt) new_args = dict() for argname, arg in six.iteritems(args): new_args[argname] = self.serializer.deserialize_entity(ctxt, arg) func = getattr(endpoint, method) span_host = tomograph.getHost() ser_name = "%s[%s]" % (func.__module__, func.__name__) tomograph.start(ser_name, func.__name__, span_host, 0, trace_info) if executor_callback: result = executor_callback(func, ctxt, **new_args) else: result = func(ctxt, **new_args) tomograph.stop(func.__name__) return self.serializer.serialize_entity(ctxt, result)
def main(self, argv): # Parse args once to find version parser = self.get_base_parser() (options, args) = parser.parse_known_args(argv) # build available subcommands based on version api_version = options.os_identity_api_version subcommand_parser = self.get_subcommand_parser(api_version) self.parser = subcommand_parser # Handle top-level --help/-h before attempting to parse # a command off the command line if not argv or options.help: self.do_help(options) return 0 # Parse args again and call whatever callback was selected args = subcommand_parser.parse_args(argv) # Short-circuit and deal with help command right away. if args.func == self.do_help: self.do_help(args) return 0 elif args.func == self.do_bash_completion: self.do_bash_completion(args) return 0 if args.debug: logging_level = logging.DEBUG iso_logger = logging.getLogger('iso8601') iso_logger.setLevel('WARN') else: logging_level = logging.WARNING logging.basicConfig(level=logging_level) # TODO(heckj): supporting backwards compatibility with environment # variables. To be removed after DEVSTACK is updated, ideally in # the Grizzly release cycle. args.os_token = args.os_token or env('SERVICE_TOKEN') args.os_endpoint = args.os_endpoint or env('SERVICE_ENDPOINT') if utils.isunauthenticated(args.func): self.cs = shell_generic.CLIENT_CLASS(endpoint=args.os_auth_url, cacert=args.os_cacert, key=args.os_key, cert=args.os_cert, insecure=args.insecure, timeout=args.timeout) else: self.auth_check(args) token = None if args.os_token and args.os_endpoint: token = args.os_token api_version = options.os_identity_api_version self.cs = self.get_api_class(api_version)( username=args.os_username, tenant_name=args.os_tenant_name, tenant_id=args.os_tenant_id, token=token, endpoint=args.os_endpoint, password=args.os_password, auth_url=args.os_auth_url, region_name=args.os_region_name, cacert=args.os_cacert, key=args.os_key, cert=args.os_cert, insecure=args.insecure, debug=args.debug, use_keyring=args.os_cache, force_new_token=args.force_new_token, stale_duration=args.stale_duration, timeout=args.timeout) try: span_host = tomograph.getHost() span_name = ' '.join(sys.argv) tomograph.start("keystoneclient-shell", span_name, span_host, 0) args.func(self.cs, args) tomograph.stop(span_name) except exc.Unauthorized: tomograph.tag("Exception", "Unauthorized") tomograph.stop(span_name) raise exc.CommandError("Invalid OpenStack Identity credentials.") except exc.AuthorizationFailure: tomograph.tag("Exception", "AuthorizationFailure") tomograph.stop(span_name) raise exc.CommandError("Unable to authorize user")
def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser() # NOTE(dtroyer): Hackery to handle --endpoint_type due to argparse # thinking usage-list --end is ambiguous; but it # works fine with only --endpoint-type present # Go figure. if '--endpoint_type' in argv: spot = argv.index('--endpoint_type') argv[spot] = '--endpoint-type' (args, args_list) = parser.parse_known_args(argv) self.setup_debugging(args.debug) self.extensions = [] do_help = ('help' in argv) or not argv # Discover available auth plugins #tomograph.annotate("Discover available auth plugins", "novaclient-shell") novaclient.auth_plugin.discover_auth_systems() if not args.os_compute_api_version: api_version = api_versions.get_api_version( DEFAULT_MAJOR_OS_COMPUTE_API_VERSION) else: api_version = api_versions.get_api_version( args.os_compute_api_version) os_username = args.os_username os_user_id = args.os_user_id os_password = None # Fetched and set later as needed os_tenant_name = args.os_tenant_name os_tenant_id = args.os_tenant_id os_auth_url = args.os_auth_url os_region_name = args.os_region_name os_auth_system = args.os_auth_system endpoint_type = args.endpoint_type insecure = args.insecure service_type = args.service_type service_name = args.service_name volume_service_name = args.volume_service_name bypass_url = args.bypass_url os_cache = args.os_cache cacert = args.os_cacert timeout = args.timeout keystone_session = None keystone_auth = None # We may have either, both or none of these. # If we have both, we don't need USERNAME, PASSWORD etc. # Fill in the blanks from the SecretsHelper if possible. # Finally, authenticate unless we have both. # Note if we don't auth we probably don't have a tenant ID so we can't # cache the token. auth_token = args.os_auth_token if args.os_auth_token else None management_url = bypass_url if bypass_url else None if os_auth_system and os_auth_system != "keystone": auth_plugin = novaclient.auth_plugin.load_plugin(os_auth_system) else: auth_plugin = None if not endpoint_type: endpoint_type = DEFAULT_NOVA_ENDPOINT_TYPE # This allow users to use endpoint_type as (internal, public or admin) # just like other openstack clients (glance, cinder etc) if endpoint_type in ['internal', 'public', 'admin']: endpoint_type += 'URL' if not service_type: # Note(alex_xu): We need discover version first, so if there isn't # service type specified, we use default nova service type. service_type = DEFAULT_NOVA_SERVICE_TYPE # If we have an auth token but no management_url, we must auth anyway. # Expired tokens are handled by client.py:_cs_request must_auth = not (auth_token and management_url) # Do not use Keystone session for cases with no session support. The # presence of auth_plugin means os_auth_system is present and is not # keystone. use_session = True if auth_plugin or bypass_url or os_cache or volume_service_name: use_session = False # FIXME(usrleon): Here should be restrict for project id same as # for os_username or os_password but for compatibility it is not. if must_auth and not do_help: if auth_plugin: auth_plugin.parse_opts(args) if not auth_plugin or not auth_plugin.opts: if not os_username and not os_user_id: raise exc.CommandError( _("You must provide a username " "or user id via --os-username, --os-user-id, " "env[OS_USERNAME] or env[OS_USER_ID]")) if not any([args.os_tenant_name, args.os_tenant_id, args.os_project_id, args.os_project_name]): raise exc.CommandError(_("You must provide a project name or" " project id via --os-project-name," " --os-project-id, env[OS_PROJECT_ID]" " or env[OS_PROJECT_NAME]. You may" " use os-project and os-tenant" " interchangeably.")) if not os_auth_url: if os_auth_system and os_auth_system != 'keystone': os_auth_url = auth_plugin.get_auth_url() if not os_auth_url: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL] " "or specify an auth_system which defines a " "default url with --os-auth-system " "or env[OS_AUTH_SYSTEM]")) project_id = args.os_project_id or args.os_tenant_id project_name = args.os_project_name or args.os_tenant_name if use_session: # Not using Nova auth plugin, so use keystone with utils.record_time(self.times, args.timings, 'auth_url', args.os_auth_url): keystone_session = (ksession.Session .load_from_cli_options(args)) keystone_auth = self._get_keystone_auth( keystone_session, args.os_auth_url, username=args.os_username, user_id=args.os_user_id, user_domain_id=args.os_user_domain_id, user_domain_name=args.os_user_domain_name, password=args.os_password, auth_token=args.os_auth_token, project_id=project_id, project_name=project_name, project_domain_id=args.os_project_domain_id, project_domain_name=args.os_project_domain_name) if not do_help and not any([args.os_tenant_id, args.os_tenant_name, args.os_project_id, args.os_project_name]): raise exc.CommandError(_("You must provide a project name or" " project id via --os-project-name," " --os-project-id, env[OS_PROJECT_ID]" " or env[OS_PROJECT_NAME]. You may" " use os-project and os-tenant" " interchangeably.")) if not os_auth_url and not do_help: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL]")) # This client is just used to discover api version. Version API needn't # microversion, so we just pass version 2 at here. #tomograph.annotate("Discover api version", "novaclient-shell") self.cs = client.Client( api_versions.APIVersion("2.0"), os_username, os_password, os_tenant_name, tenant_id=os_tenant_id, user_id=os_user_id, auth_url=os_auth_url, insecure=insecure, region_name=os_region_name, endpoint_type=endpoint_type, extensions=self.extensions, service_type=service_type, service_name=service_name, auth_system=os_auth_system, auth_plugin=auth_plugin, auth_token=auth_token, volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, os_cache=os_cache, http_log_debug=args.debug, cacert=cacert, timeout=timeout, session=keystone_session, auth=keystone_auth) if not do_help: if not api_version.is_latest(): if api_version > api_versions.APIVersion("2.0"): if not api_version.matches(novaclient.API_MIN_VERSION, novaclient.API_MAX_VERSION): raise exc.CommandError( _("The specified version isn't supported by " "client. The valid version range is '%(min)s' " "to '%(max)s'") % { "min": novaclient.API_MIN_VERSION.get_string(), "max": novaclient.API_MAX_VERSION.get_string()} ) api_version = api_versions.discover_version(self.cs, api_version) # build available subcommands based on version self.extensions = client.discover_extensions(api_version) self._run_extension_hooks('__pre_parse_args__') subcommand_parser = self.get_subcommand_parser( api_version, do_help=do_help) self.parser = subcommand_parser if args.help or not argv: subcommand_parser.print_help() return 0 args = subcommand_parser.parse_args(argv) self._run_extension_hooks('__post_parse_args__', args) # Short-circuit and deal with help right away. if args.func == self.do_help: self.do_help(args) return 0 elif args.func == self.do_bash_completion: self.do_bash_completion(args) return 0 if not args.service_type: service_type = (cliutils.get_service_type(args.func) or DEFAULT_NOVA_SERVICE_TYPE) if cliutils.isunauthenticated(args.func): # NOTE(alex_xu): We need authentication for discover microversion. # But the subcommands may needn't it. If the subcommand needn't, # we clear the session arguements. keystone_session = None keystone_auth = None # Recreate client object with discovered version. self.cs = client.Client( api_version, os_username, os_password, os_tenant_name, tenant_id=os_tenant_id, user_id=os_user_id, auth_url=os_auth_url, insecure=insecure, region_name=os_region_name, endpoint_type=endpoint_type, extensions=self.extensions, service_type=service_type, service_name=service_name, auth_system=os_auth_system, auth_plugin=auth_plugin, auth_token=auth_token, volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, os_cache=os_cache, http_log_debug=args.debug, cacert=cacert, timeout=timeout, session=keystone_session, auth=keystone_auth) # Now check for the password/token of which pieces of the # identifying keyring key can come from the underlying client span_host = tomograph.getHost() span_name = ' '.join(sys.argv) # for arg in argv: # if arg[0] is not '-': # span_name = span_name + ' ' + arg tomograph.start("novaclient-shell", span_name, span_host, 0) if must_auth: helper = SecretsHelper(args, self.cs.client) self.cs.client.keyring_saver = helper if (auth_plugin and auth_plugin.opts and "os_password" not in auth_plugin.opts): use_pw = False else: use_pw = True tenant_id = helper.tenant_id # Allow commandline to override cache if not auth_token: auth_token = helper.auth_token if not management_url: management_url = helper.management_url if tenant_id and auth_token and management_url: self.cs.client.tenant_id = tenant_id self.cs.client.auth_token = auth_token self.cs.client.management_url = management_url self.cs.client.password_func = lambda: helper.password elif use_pw: # We're missing something, so auth with user/pass and save # the result in our helper. self.cs.client.password = helper.password try: # This does a couple of bits which are useful even if we've # got the token + service URL already. It exits fast in that case. if not cliutils.isunauthenticated(args.func): if not use_session: # Only call authenticate() if Nova auth plugin is used. # If keystone is used, authentication is handled as part # of session. self.cs.authenticate() except exc.Unauthorized: tomograph.tag("Exception", "Unauthorized") tomograph.stop(span_name) raise exc.CommandError(_("Invalid OpenStack Nova credentials.")) except exc.AuthorizationFailure: tomograph.tag("Exception", "AuthorizationFailure") tomograph.stop(span_name) raise exc.CommandError(_("Unable to authorize user")) args.func(self.cs, args) if args.timings: self._dump_timings(self.times + self.cs.get_timings()) tomograph.stop(span_name)
def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser() # NOTE(dtroyer): Hackery to handle --endpoint_type due to argparse # thinking usage-list --end is ambiguous; but it # works fine with only --endpoint-type present # Go figure. if '--endpoint_type' in argv: spot = argv.index('--endpoint_type') argv[spot] = '--endpoint-type' (args, args_list) = parser.parse_known_args(argv) self.setup_debugging(args.debug) self.extensions = [] do_help = ('help' in argv) or not argv # Discover available auth plugins #tomograph.annotate("Discover available auth plugins", "novaclient-shell") novaclient.auth_plugin.discover_auth_systems() if not args.os_compute_api_version: api_version = api_versions.get_api_version( DEFAULT_MAJOR_OS_COMPUTE_API_VERSION) else: api_version = api_versions.get_api_version( args.os_compute_api_version) os_username = args.os_username os_user_id = args.os_user_id os_password = None # Fetched and set later as needed os_tenant_name = args.os_tenant_name os_tenant_id = args.os_tenant_id os_auth_url = args.os_auth_url os_region_name = args.os_region_name os_auth_system = args.os_auth_system endpoint_type = args.endpoint_type insecure = args.insecure service_type = args.service_type service_name = args.service_name volume_service_name = args.volume_service_name bypass_url = args.bypass_url os_cache = args.os_cache cacert = args.os_cacert timeout = args.timeout keystone_session = None keystone_auth = None # We may have either, both or none of these. # If we have both, we don't need USERNAME, PASSWORD etc. # Fill in the blanks from the SecretsHelper if possible. # Finally, authenticate unless we have both. # Note if we don't auth we probably don't have a tenant ID so we can't # cache the token. auth_token = args.os_auth_token if args.os_auth_token else None management_url = bypass_url if bypass_url else None if os_auth_system and os_auth_system != "keystone": auth_plugin = novaclient.auth_plugin.load_plugin(os_auth_system) else: auth_plugin = None if not endpoint_type: endpoint_type = DEFAULT_NOVA_ENDPOINT_TYPE # This allow users to use endpoint_type as (internal, public or admin) # just like other openstack clients (glance, cinder etc) if endpoint_type in ['internal', 'public', 'admin']: endpoint_type += 'URL' if not service_type: # Note(alex_xu): We need discover version first, so if there isn't # service type specified, we use default nova service type. service_type = DEFAULT_NOVA_SERVICE_TYPE # If we have an auth token but no management_url, we must auth anyway. # Expired tokens are handled by client.py:_cs_request must_auth = not (auth_token and management_url) # Do not use Keystone session for cases with no session support. The # presence of auth_plugin means os_auth_system is present and is not # keystone. use_session = True if auth_plugin or bypass_url or os_cache or volume_service_name: use_session = False # FIXME(usrleon): Here should be restrict for project id same as # for os_username or os_password but for compatibility it is not. if must_auth and not do_help: if auth_plugin: auth_plugin.parse_opts(args) if not auth_plugin or not auth_plugin.opts: if not os_username and not os_user_id: raise exc.CommandError( _("You must provide a username " "or user id via --os-username, --os-user-id, " "env[OS_USERNAME] or env[OS_USER_ID]")) if not any([ args.os_tenant_name, args.os_tenant_id, args.os_project_id, args.os_project_name ]): raise exc.CommandError( _("You must provide a project name or" " project id via --os-project-name," " --os-project-id, env[OS_PROJECT_ID]" " or env[OS_PROJECT_NAME]. You may" " use os-project and os-tenant" " interchangeably.")) if not os_auth_url: if os_auth_system and os_auth_system != 'keystone': os_auth_url = auth_plugin.get_auth_url() if not os_auth_url: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL] " "or specify an auth_system which defines a " "default url with --os-auth-system " "or env[OS_AUTH_SYSTEM]")) project_id = args.os_project_id or args.os_tenant_id project_name = args.os_project_name or args.os_tenant_name if use_session: # Not using Nova auth plugin, so use keystone with utils.record_time(self.times, args.timings, 'auth_url', args.os_auth_url): keystone_session = ( ksession.Session.load_from_cli_options(args)) keystone_auth = self._get_keystone_auth( keystone_session, args.os_auth_url, username=args.os_username, user_id=args.os_user_id, user_domain_id=args.os_user_domain_id, user_domain_name=args.os_user_domain_name, password=args.os_password, auth_token=args.os_auth_token, project_id=project_id, project_name=project_name, project_domain_id=args.os_project_domain_id, project_domain_name=args.os_project_domain_name) if not do_help and not any([ args.os_tenant_id, args.os_tenant_name, args.os_project_id, args.os_project_name ]): raise exc.CommandError( _("You must provide a project name or" " project id via --os-project-name," " --os-project-id, env[OS_PROJECT_ID]" " or env[OS_PROJECT_NAME]. You may" " use os-project and os-tenant" " interchangeably.")) if not os_auth_url and not do_help: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL]")) # This client is just used to discover api version. Version API needn't # microversion, so we just pass version 2 at here. #tomograph.annotate("Discover api version", "novaclient-shell") self.cs = client.Client(api_versions.APIVersion("2.0"), os_username, os_password, os_tenant_name, tenant_id=os_tenant_id, user_id=os_user_id, auth_url=os_auth_url, insecure=insecure, region_name=os_region_name, endpoint_type=endpoint_type, extensions=self.extensions, service_type=service_type, service_name=service_name, auth_system=os_auth_system, auth_plugin=auth_plugin, auth_token=auth_token, volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, os_cache=os_cache, http_log_debug=args.debug, cacert=cacert, timeout=timeout, session=keystone_session, auth=keystone_auth) if not do_help: if not api_version.is_latest(): if api_version > api_versions.APIVersion("2.0"): if not api_version.matches(novaclient.API_MIN_VERSION, novaclient.API_MAX_VERSION): raise exc.CommandError( _("The specified version isn't supported by " "client. The valid version range is '%(min)s' " "to '%(max)s'") % { "min": novaclient.API_MIN_VERSION.get_string(), "max": novaclient.API_MAX_VERSION.get_string() }) api_version = api_versions.discover_version(self.cs, api_version) # build available subcommands based on version self.extensions = client.discover_extensions(api_version) self._run_extension_hooks('__pre_parse_args__') subcommand_parser = self.get_subcommand_parser(api_version, do_help=do_help) self.parser = subcommand_parser if args.help or not argv: subcommand_parser.print_help() return 0 args = subcommand_parser.parse_args(argv) self._run_extension_hooks('__post_parse_args__', args) # Short-circuit and deal with help right away. if args.func == self.do_help: self.do_help(args) return 0 elif args.func == self.do_bash_completion: self.do_bash_completion(args) return 0 if not args.service_type: service_type = (cliutils.get_service_type(args.func) or DEFAULT_NOVA_SERVICE_TYPE) if cliutils.isunauthenticated(args.func): # NOTE(alex_xu): We need authentication for discover microversion. # But the subcommands may needn't it. If the subcommand needn't, # we clear the session arguements. keystone_session = None keystone_auth = None # Recreate client object with discovered version. self.cs = client.Client(api_version, os_username, os_password, os_tenant_name, tenant_id=os_tenant_id, user_id=os_user_id, auth_url=os_auth_url, insecure=insecure, region_name=os_region_name, endpoint_type=endpoint_type, extensions=self.extensions, service_type=service_type, service_name=service_name, auth_system=os_auth_system, auth_plugin=auth_plugin, auth_token=auth_token, volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, os_cache=os_cache, http_log_debug=args.debug, cacert=cacert, timeout=timeout, session=keystone_session, auth=keystone_auth) # Now check for the password/token of which pieces of the # identifying keyring key can come from the underlying client span_host = tomograph.getHost() span_name = ' '.join(sys.argv) # for arg in argv: # if arg[0] is not '-': # span_name = span_name + ' ' + arg tomograph.start("novaclient-shell", span_name, span_host, 0) if must_auth: helper = SecretsHelper(args, self.cs.client) self.cs.client.keyring_saver = helper if (auth_plugin and auth_plugin.opts and "os_password" not in auth_plugin.opts): use_pw = False else: use_pw = True tenant_id = helper.tenant_id # Allow commandline to override cache if not auth_token: auth_token = helper.auth_token if not management_url: management_url = helper.management_url if tenant_id and auth_token and management_url: self.cs.client.tenant_id = tenant_id self.cs.client.auth_token = auth_token self.cs.client.management_url = management_url self.cs.client.password_func = lambda: helper.password elif use_pw: # We're missing something, so auth with user/pass and save # the result in our helper. self.cs.client.password = helper.password try: # This does a couple of bits which are useful even if we've # got the token + service URL already. It exits fast in that case. if not cliutils.isunauthenticated(args.func): if not use_session: # Only call authenticate() if Nova auth plugin is used. # If keystone is used, authentication is handled as part # of session. self.cs.authenticate() except exc.Unauthorized: tomograph.tag("Exception", "Unauthorized") tomograph.stop(span_name) raise exc.CommandError(_("Invalid OpenStack Nova credentials.")) except exc.AuthorizationFailure: tomograph.tag("Exception", "AuthorizationFailure") tomograph.stop(span_name) raise exc.CommandError(_("Unable to authorize user")) args.func(self.cs, args) if args.timings: self._dump_timings(self.times + self.cs.get_timings()) tomograph.stop(span_name)
def main(self, argv): # Parse args once to find version # NOTE(flepied) Under Python3, parsed arguments are removed # from the list so make a copy for the first parsing base_argv = copy.deepcopy(argv) parser = self.get_base_parser() (options, args) = parser.parse_known_args(base_argv) span_host = tomograph.getHost() span_name = ' '.join(sys.argv) tomograph.start("glanceclient-shell", span_name, span_host, 0) try: # NOTE(flaper87): Try to get the version from the # image-url first. If no version was specified, fallback # to the api-image-version arg. If both of these fail then # fallback to the minimum supported one and let keystone # do the magic. endpoint = self._get_image_url(options) endpoint, url_version = utils.strip_version(endpoint) except ValueError: # NOTE(flaper87): ValueError is raised if no endpoint is povided url_version = None # build available subcommands based on version try: api_version = int(options.os_image_api_version or url_version or 2) if api_version not in SUPPORTED_VERSIONS: raise ValueError except ValueError: msg = ("Invalid API version parameter. " "Supported values are %s" % SUPPORTED_VERSIONS) utils.exit(msg=msg) if api_version == 2: switch_version = self._cache_schemas(options) if switch_version: print('WARNING: The client is falling back to v1 because' ' the accessing to v2 failed. This behavior will' ' be removed in future versions') api_version = 1 try: subcommand_parser = self.get_subcommand_parser(api_version) except ImportError as e: if options.debug: traceback.print_exc() if not str(e): # Add a generic import error message if the raised ImportError # has none. raise ImportError('Unable to import module. Re-run ' 'with --debug for more info.') raise except Exception: if options.debug: traceback.print_exc() raise self.parser = subcommand_parser # Handle top-level --help/-h before attempting to parse # a command off the command line if options.help or not argv: self.do_help(options) return 0 # Parse args again and call whatever callback was selected args = subcommand_parser.parse_args(argv) # Short-circuit and deal with help command right away. if args.func == self.do_help: self.do_help(args) return 0 elif args.func == self.do_bash_completion: self.do_bash_completion(args) return 0 LOG = logging.getLogger('glanceclient') LOG.addHandler(logging.StreamHandler()) LOG.setLevel(logging.DEBUG if args.debug else logging.INFO) profile = osprofiler_profiler and options.profile if profile: osprofiler_profiler.init(options.profile) client = self._get_versioned_client(api_version, args, force_auth=False) try: # pdb.set_trace() args.func(client, args) except exc.Unauthorized: raise exc.CommandError("Invalid OpenStack Identity credentials.") except Exception: # NOTE(kragniz) Print any exceptions raised to stderr if the # --debug flag is set if args.debug: traceback.print_exc() raise finally: tomograph.stop(span_name) if profile: trace_id = osprofiler_profiler.get().get_base_id() print("Profiling trace ID: %s" % trace_id) print("To display trace use next command:\n" "osprofiler trace show --html %s " % trace_id)