def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser() (options, args) = parser.parse_known_args(argv) self.setup_debugging(options.debug) # Discover available auth plugins novaclient.auth_plugin.discover_auth_systems() # build available subcommands based on version self.extensions = self._discover_extensions( options.os_compute_api_version) self._run_extension_hooks('__pre_parse_args__') # 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' subcommand_parser = self.get_subcommand_parser( options.os_compute_api_version) self.parser = subcommand_parser if options.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 (os_username, os_tenant_name, os_auth_url, os_region_name, os_auth_system, endpoint_type, insecure, service_type, service_name, volume_service_name, bypass_url, os_cache, cacert, timeout) = ( args.os_username, args.os_tenant_name, args.os_auth_url, args.os_region_name, args.os_auth_system, args.endpoint_type, args.insecure, args.service_type, args.service_name, args.volume_service_name, args.bypass_url, args.os_cache, args.os_cacert, args.timeout) if os_auth_system and os_auth_system != "keystone": auth_plugin = novaclient.auth_plugin.load_plugin(os_auth_system) else: auth_plugin = None # Fetched and set later as needed os_password = None if not endpoint_type: endpoint_type = DEFAULT_NOVA_ENDPOINT_TYPE if not service_type: service_type = DEFAULT_NOVA_SERVICE_TYPE service_type = utils.get_service_type(args.func) or service_type #FIXME(usrleon): Here should be restrict for project id same as # for os_username or os_password but for compatibility it is not. if not utils.isunauthenticated(args.func): if auth_plugin: auth_plugin.parse_opts(args) if not auth_plugin or not auth_plugin.opts: if not os_username: raise exc.CommandError("You must provide a username " "via either --os-username or env[OS_USERNAME]") if not os_tenant_name: raise exc.CommandError("You must provide a tenant name " "via either --os-tenant-name or " "env[OS_TENANT_NAME]") 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]") if (options.os_compute_api_version and options.os_compute_api_version != '1.0'): if not os_tenant_name: raise exc.CommandError("You must provide a tenant name " "via either --os-tenant-name or env[OS_TENANT_NAME]") if not os_auth_url: raise exc.CommandError("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL]") self.cs = client.Client(options.os_compute_api_version, os_username, os_password, os_tenant_name, os_auth_url, 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, volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, os_cache=os_cache, http_log_debug=options.debug, cacert=cacert, timeout=timeout) # Now check for the password/token of which pieces of the # identifying keyring key can come from the underlying client if not utils.isunauthenticated(args.func): helper = SecretsHelper(args, self.cs.client) if (auth_plugin and auth_plugin.opts and "os_password" not in auth_plugin.opts): use_pw = False else: use_pw = True tenant_id, auth_token, management_url = (helper.tenant_id, helper.auth_token, 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 # Try to auth with the given info, if it fails # go into password mode... try: self.cs.authenticate() use_pw = False except (exc.Unauthorized, exc.AuthorizationFailure): # Likely it expired or just didn't work... self.cs.client.auth_token = None self.cs.client.management_url = None if use_pw: # Auth using token must have failed or not happened # at all, so now switch to password mode and save # the token when its gotten... using our keyring # saver os_password = helper.password if not os_password: raise exc.CommandError( 'Expecting a password provided via either ' '--os-password, env[OS_PASSWORD], or ' 'prompted response') self.cs.client.password = os_password self.cs.client.keyring_saver = helper try: if not utils.isunauthenticated(args.func): self.cs.authenticate() except exc.Unauthorized: raise exc.CommandError("Invalid OpenStack Nova credentials.") except exc.AuthorizationFailure: raise exc.CommandError("Unable to authorize user") args.func(self.cs, args) if args.timings: self._dump_timings(self.cs.get_timings())
def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser() (options, args) = parser.parse_known_args(argv) self.setup_debugging(options.debug) # Discover available auth plugins novaclient.auth_plugin.discover_auth_systems() # build available subcommands based on version self.extensions = self._discover_extensions( options.os_compute_api_version) self._run_extension_hooks('__pre_parse_args__') # 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' subcommand_parser = self.get_subcommand_parser( options.os_compute_api_version) self.parser = subcommand_parser if options.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 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 # 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 if not service_type: os_compute_api_version = (options.os_compute_api_version or DEFAULT_OS_COMPUTE_API_VERSION) try: service_type = DEFAULT_NOVA_SERVICE_TYPE_MAP[ os_compute_api_version] except KeyError: service_type = DEFAULT_NOVA_SERVICE_TYPE_MAP[ DEFAULT_OS_COMPUTE_API_VERSION] service_type = utils.get_service_type(args.func) or 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 (cliutils.isunauthenticated(args.func) or (auth_token and management_url)) # 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: 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 os_tenant_name and not os_tenant_id: raise exc.CommandError(_("You must provide a tenant name " "or tenant id via --os-tenant-name, " "--os-tenant-id, env[OS_TENANT_NAME] " "or env[OS_TENANT_ID]")) 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]")) if (options.os_compute_api_version and options.os_compute_api_version != '1.0'): if not os_tenant_name and not os_tenant_id: raise exc.CommandError(_("You must provide a tenant name " "or tenant id via --os-tenant-name, " "--os-tenant-id, env[OS_TENANT_NAME] " "or env[OS_TENANT_ID]")) if not os_auth_url: raise exc.CommandError(_("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL]")) completion_cache = client.CompletionCache(os_username, os_auth_url) self.cs = client.Client(options.os_compute_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=options.debug, cacert=cacert, timeout=timeout, completion_cache=completion_cache) # Now check for the password/token of which pieces of the # identifying keyring key can come from the underlying client if must_auth: helper = SecretsHelper(args, self.cs.client) 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 self.cs.client.keyring_saver = helper 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): self.cs.authenticate() except exc.Unauthorized: raise exc.CommandError(_("Invalid OpenStack Nova credentials.")) except exc.AuthorizationFailure: raise exc.CommandError(_("Unable to authorize user")) if options.os_compute_api_version == "3" and service_type != 'image': # NOTE(cyeoh): create an image based client because the # images api is no longer proxied by the V3 API and we # sometimes need to be able to look up images information # via glance when connected to the nova api. image_service_type = 'image' # NOTE(hdd): the password is needed again because creating a new # Client without specifying bypass_url will force authentication. # We can't reuse self.cs's bypass_url, because that's the URL for # the nova service; we need to get glance's URL for this Client if not os_password: os_password = helper.password self.cs.image_cs = client.Client( options.os_compute_api_version, os_username, os_password, os_tenant_name, tenant_id=os_tenant_id, auth_url=os_auth_url, insecure=insecure, region_name=os_region_name, endpoint_type=endpoint_type, extensions=self.extensions, service_type=image_service_type, service_name=service_name, auth_system=os_auth_system, auth_plugin=auth_plugin, volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, os_cache=os_cache, http_log_debug=options.debug, cacert=cacert, timeout=timeout) args.func(self.cs, args) if args.timings: self._dump_timings(self.cs.get_timings())
def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser(argv) (args, args_list) = parser.parse_known_args(argv) self.setup_debugging(args.debug) self.extensions = [] do_help = args.help or not args_list or args_list[0] == 'help' # bash-completion should not require authentication skip_auth = do_help or ( 'bash-completion' in argv) 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_project_name = getattr( args, 'os_project_name', getattr(args, 'os_tenant_name', None)) os_project_id = getattr( args, 'os_project_id', getattr(args, 'os_tenant_id', None)) os_auth_url = args.os_auth_url os_region_name = args.os_region_name if "v2.0" not in os_auth_url: # NOTE(andreykurilin): assume that keystone V3 is used and try to # be more user-friendly, i.e provide default values for domains if (not args.os_project_domain_id and not args.os_project_domain_name): setattr(args, "os_project_domain_id", "default") if not args.os_user_domain_id and not args.os_user_domain_name: setattr(args, "os_user_domain_id", "default") os_project_domain_id = args.os_project_domain_id os_project_domain_name = args.os_project_domain_name os_user_domain_id = args.os_project_domain_id os_user_domain_name = args.os_project_domain_name endpoint_type = args.endpoint_type insecure = args.insecure service_type = args.service_type service_name = args.service_name endpoint_override = args.endpoint_override os_cache = args.os_cache cacert = args.os_cacert cert = args.os_cert 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 = getattr(args, 'os_token', 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 # We should always auth unless we have a token and we're passing a # specific endpoint # Expired tokens are handled by client.py:_cs_request must_auth = not (auth_token and endpoint_override) # 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 skip_auth: 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([os_project_name, os_project_id]): 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: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL].")) with utils.record_time(self.times, args.timings, 'auth_url', args.os_auth_url): keystone_session = ( loading.load_session_from_argparse_arguments(args)) keystone_auth = ( loading.load_auth_from_argparse_arguments(args)) if (not skip_auth and not any([os_project_name, os_project_id])): 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 skip_auth: 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. self.cs = client.Client( api_versions.APIVersion("2.0"), os_username, os_password, project_id=os_project_id, project_name=os_project_name, 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_token=auth_token, timings=args.timings, endpoint_override=endpoint_override, os_cache=os_cache, http_log_debug=args.debug, cacert=cacert, cert=cert, timeout=timeout, session=keystone_session, auth=keystone_auth, logger=self.client_logger, project_domain_id=os_project_domain_id, project_domain_name=os_project_domain_name, user_domain_id=os_user_domain_id, user_domain_name=os_user_domain_name) if not skip_auth: 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, argv=argv) 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 = (utils.get_service_type(args.func) or DEFAULT_NOVA_SERVICE_TYPE) if utils.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 arguments. keystone_session = None keystone_auth = None # Recreate client object with discovered version. self.cs = client.Client( api_version, os_username, os_password, os_project_name, tenant_id=os_project_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_token=auth_token, timings=args.timings, endpoint_override=endpoint_override, os_cache=os_cache, http_log_debug=args.debug, cacert=cacert, cert=cert, timeout=timeout, session=keystone_session, auth=keystone_auth, project_domain_id=os_project_domain_id, project_domain_name=os_project_domain_name, user_domain_id=os_user_domain_id, user_domain_name=os_user_domain_name) # Now check for the password/token of which pieces of the # identifying keyring key can come from the underlying client if must_auth: helper = SecretsHelper(args, self.cs.client) self.cs.client.keyring_saver = helper tenant_id = helper.tenant_id # Allow commandline to override cache if not auth_token: auth_token = helper.auth_token endpoint_override = endpoint_override or helper.management_url if tenant_id and auth_token and endpoint_override: self.cs.client.tenant_id = tenant_id self.cs.client.auth_token = auth_token self.cs.client.management_url = endpoint_override self.cs.client.password_func = lambda: helper.password else: # We're missing something, so auth with user/pass and save # the result in our helper. self.cs.client.password = helper.password args.func(self.cs, args) if args.timings: self._dump_timings(self.times + self.cs.get_timings())
def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser() (options, args) = parser.parse_known_args(argv) self.setup_debugging(options.debug) # build available subcommands based on version self.extensions = self._discover_extensions( options.os_compute_api_version) self._run_extension_hooks('__pre_parse_args__') # 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' subcommand_parser = self.get_subcommand_parser( options.os_compute_api_version) self.parser = subcommand_parser if options.help and len(args) == 0: 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 (os_username, os_password, os_tenant_name, os_auth_url, os_region_name, os_auth_system, endpoint_type, insecure, service_type, service_name, volume_service_name, username, apikey, projectid, url, region_name, bypass_url, no_cache) = ( args.os_username, args.os_password, args.os_tenant_name, args.os_auth_url, args.os_region_name, args.os_auth_system, args.endpoint_type, args.insecure, args.service_type, args.service_name, args.volume_service_name, args.username, args.apikey, args.projectid, args.url, args.region_name, args.bypass_url, args.no_cache) if not endpoint_type: endpoint_type = DEFAULT_NOVA_ENDPOINT_TYPE if not service_type: service_type = DEFAULT_NOVA_SERVICE_TYPE service_type = utils.get_service_type(args.func) or service_type #FIXME(usrleon): Here should be restrict for project id same as # for os_username or os_password but for compatibility it is not. if not utils.isunauthenticated(args.func): if not os_username: if not username: raise exc.CommandError("You must provide a username " "via either --os-username or env[OS_USERNAME]") else: os_username = username if not os_password: if not apikey: raise exc.CommandError("You must provide a password " "via either --os-password or via " "env[OS_PASSWORD]") else: os_password = apikey if not os_tenant_name: if not projectid: raise exc.CommandError("You must provide a tenant name " "via either --os-tenant-name or " "env[OS_TENANT_NAME]") else: os_tenant_name = projectid if not os_auth_url: if not url: if os_auth_system and os_auth_system != 'keystone': os_auth_url = \ client.get_auth_system_url(os_auth_system) else: os_auth_url = 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") if not os_region_name and region_name: os_region_name = region_name if (options.os_compute_api_version and options.os_compute_api_version != '1.0'): if not os_tenant_name: raise exc.CommandError("You must provide a tenant name " "via either --os-tenant-name or env[OS_TENANT_NAME]") if not os_auth_url: raise exc.CommandError("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL]") self.cs = client.Client(options.os_compute_api_version, os_username, os_password, os_tenant_name, os_auth_url, 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, volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, no_cache=no_cache, http_log_debug=options.debug) try: if not utils.isunauthenticated(args.func): self.cs.authenticate() except exc.Unauthorized: raise exc.CommandError("Invalid OpenStack Nova credentials.") except exc.AuthorizationFailure: raise exc.CommandError("Unable to authorize user") args.func(self.cs, args) if args.timings: self._dump_timings(self.cs.get_timings())
def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser() (options, args) = parser.parse_known_args(argv) self.setup_debugging(options.debug) # build available subcommands based on version self.extensions = self._discover_extensions( options.os_compute_api_version) self._run_extension_hooks('__pre_parse_args__') # 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' subcommand_parser = self.get_subcommand_parser( options.os_compute_api_version) self.parser = subcommand_parser if options.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 (os_username, os_tenant_name, os_auth_url, os_region_name, os_auth_system, endpoint_type, insecure, service_type, service_name, volume_service_name, username, projectid, url, region_name, bypass_url, os_cache, cacert, timeout) = (args.os_username, args.os_tenant_name, args.os_auth_url, args.os_region_name, args.os_auth_system, args.endpoint_type, args.insecure, args.service_type, args.service_name, args.volume_service_name, args.username, args.projectid, args.url, args.region_name, args.bypass_url, args.os_cache, args.os_cacert, args.timeout) # Fetched and set later as needed os_password = None if not endpoint_type: endpoint_type = DEFAULT_NOVA_ENDPOINT_TYPE if not service_type: service_type = DEFAULT_NOVA_SERVICE_TYPE service_type = utils.get_service_type(args.func) or service_type #FIXME(usrleon): Here should be restrict for project id same as # for os_username or os_password but for compatibility it is not. if not utils.isunauthenticated(args.func): if not os_username: if not username: raise exc.CommandError( "You must provide a username " "via either --os-username or env[OS_USERNAME]") else: os_username = username if not os_tenant_name: if not projectid: raise exc.CommandError("You must provide a tenant name " "via either --os-tenant-name or " "env[OS_TENANT_NAME]") else: os_tenant_name = projectid if not os_auth_url: if not url: if os_auth_system and os_auth_system != 'keystone': os_auth_url = \ client.get_auth_system_url(os_auth_system) else: os_auth_url = 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]") if not os_region_name and region_name: os_region_name = region_name if (options.os_compute_api_version and options.os_compute_api_version != '1.0'): if not os_tenant_name: raise exc.CommandError( "You must provide a tenant name " "via either --os-tenant-name or env[OS_TENANT_NAME]") if not os_auth_url: raise exc.CommandError( "You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL]") self.cs = client.Client(options.os_compute_api_version, os_username, os_password, os_tenant_name, os_auth_url, 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, volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, os_cache=os_cache, http_log_debug=options.debug, cacert=cacert, timeout=timeout) # Now check for the password/token of which pieces of the # identifying keyring key can come from the underlying client if not utils.isunauthenticated(args.func): helper = SecretsHelper(args, self.cs.client) use_pw = True tenant_id, auth_token, management_url = (helper.tenant_id, helper.auth_token, 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 # Try to auth with the given info, if it fails # go into password mode... try: self.cs.authenticate() use_pw = False except (exc.Unauthorized, exc.AuthorizationFailure): # Likely it expired or just didn't work... self.cs.client.auth_token = None self.cs.client.management_url = None if use_pw: # Auth using token must have failed or not happened # at all, so now switch to password mode and save # the token when its gotten... using our keyring # saver os_password = helper.password if not os_password: raise exc.CommandError( 'Expecting a password provided via either ' '--os-password, env[OS_PASSWORD], or ' 'prompted response') self.cs.client.password = os_password self.cs.client.keyring_saver = helper try: if not utils.isunauthenticated(args.func): self.cs.authenticate() except exc.Unauthorized: raise exc.CommandError("Invalid OpenStack Nova credentials.") except exc.AuthorizationFailure: raise exc.CommandError("Unable to authorize user") args.func(self.cs, args) if args.timings: self._dump_timings(self.cs.get_timings())
def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser(argv) (args, args_list) = parser.parse_known_args(argv) self.setup_debugging(args.debug) self.extensions = [] do_help = args.help or not args_list or args_list[0] == 'help' # bash-completion should not require authentication skip_auth = do_help or ('bash-completion' in argv) 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) auth_token = getattr(args, "os_token", None) os_username = getattr(args, "os_username", None) os_user_id = getattr(args, "os_user_id", None) os_password = None # Fetched and set later as needed os_project_name = getattr(args, 'os_project_name', getattr(args, 'os_tenant_name', None)) os_project_id = getattr(args, 'os_project_id', getattr(args, 'os_tenant_id', None)) os_auth_url = args.os_auth_url os_region_name = args.os_region_name if "v2.0" not in os_auth_url: # NOTE(andreykurilin): assume that keystone V3 is used and try to # be more user-friendly, i.e provide default values for domains if (not args.os_project_domain_id and not args.os_project_domain_name): setattr(args, "os_project_domain_id", "default") # os_user_domain_id is redundant in case of Token auth type if not auth_token and (not args.os_user_domain_id and not args.os_user_domain_name): setattr(args, "os_user_domain_id", "default") os_project_domain_id = args.os_project_domain_id os_project_domain_name = args.os_project_domain_name os_user_domain_id = getattr(args, "os_user_domain_id", None) os_user_domain_name = getattr(args, "os_user_domain_name", None) endpoint_type = args.endpoint_type insecure = args.insecure service_type = args.service_type service_name = args.service_name endpoint_override = args.endpoint_override os_cache = args.os_cache cacert = args.os_cacert cert = args.os_cert timeout = args.timeout keystone_session = None keystone_auth = 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 # We should always auth unless we have a token and we're passing a # specific endpoint # Expired tokens are handled by client.py:_cs_request must_auth = not (auth_token and endpoint_override) # 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 skip_auth: if not any([auth_token, os_username, os_user_id]): raise exc.CommandError( _("You must provide a user name/id (via --os-username, " "--os-user-id, env[OS_USERNAME] or env[OS_USER_ID]) or " "an auth token (via --os-token).")) if not any([os_project_name, os_project_id]): 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: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL].")) # TODO(Shilpasd): need to provide support in python - novaclient # for required options for below default auth type plugins: # 1. v3oidcclientcredential # 2. v3oidcpassword # 3. v3oidcauthcode # 4. v3oidcaccesstoken # 5. v3oauth1 # 6. v3fedkerb # 7. v3adfspassword # 8. v3samlpassword # 9. v3applicationcredential # TODO(Shilpasd): need to provide support in python - novaclient # for below extra keystoneauth auth type plugins: # We will need to add code to support discovering of versions # supported by the keystone service based on the auth_url similar # to the one supported by glanceclient. # 1. v3password # 2. v3token # 3. v3kerberos # 4. v3totp with utils.record_time(self.times, args.timings, 'auth_url', args.os_auth_url): keystone_session = ( loading.load_session_from_argparse_arguments(args)) keystone_auth = ( loading.load_auth_from_argparse_arguments(args)) if (not skip_auth and not any([os_project_name, os_project_id])): 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 skip_auth: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL]")) additional_kwargs = {} if osprofiler_profiler: additional_kwargs["profile"] = args.profile # This client is just used to discover api version. Version API needn't # microversion, so we just pass version 2 at here. self.cs = client.Client(api_versions.APIVersion("2.0"), os_username, os_password, project_id=os_project_id, project_name=os_project_name, 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_token=auth_token, timings=args.timings, endpoint_override=endpoint_override, os_cache=os_cache, http_log_debug=args.debug, cacert=cacert, cert=cert, timeout=timeout, session=keystone_session, auth=keystone_auth, logger=self.client_logger, project_domain_id=os_project_domain_id, project_domain_name=os_project_domain_name, user_domain_id=os_user_domain_id, user_domain_name=os_user_domain_name, **additional_kwargs) if not skip_auth: 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, argv=argv) 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 = (utils.get_service_type(args.func) or DEFAULT_NOVA_SERVICE_TYPE) if utils.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 arguments. keystone_session = None keystone_auth = None # Recreate client object with discovered version. self.cs = client.Client(api_version, os_username, os_password, project_id=os_project_id, project_name=os_project_name, 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_token=auth_token, timings=args.timings, endpoint_override=endpoint_override, os_cache=os_cache, http_log_debug=args.debug, cacert=cacert, cert=cert, timeout=timeout, session=keystone_session, auth=keystone_auth, project_domain_id=os_project_domain_id, project_domain_name=os_project_domain_name, user_domain_id=os_user_domain_id, user_domain_name=os_user_domain_name) args.func(self.cs, args) if osprofiler_profiler and args.profile: trace_id = osprofiler_profiler.get().get_base_id() print("To display trace use the command:\n\n" " osprofiler trace show --html %s " % trace_id) if args.timings: self._dump_timings(self.times + self.cs.get_timings())
def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser(argv) (args, args_list) = parser.parse_known_args(argv) self.setup_debugging(args.debug) self.extensions = [] do_help = ('help' in argv) or ('--help' in argv) or ('-h' in argv) or not argv # bash-completion should not require authentication skip_auth = do_help or ('bash-completion' in argv) # Discover available auth plugins 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_project_name = getattr(args, 'os_project_name', getattr(args, 'os_tenant_name', None)) os_project_id = getattr(args, 'os_project_id', getattr(args, 'os_tenant_id', None)) os_auth_url = args.os_auth_url os_region_name = args.os_region_name os_auth_system = args.os_auth_system if "v2.0" not in os_auth_url: # NOTE(andreykurilin): assume that keystone V3 is used and try to # be more user-friendly, i.e provide default values for domains if (not args.os_project_domain_id and not args.os_project_domain_name): setattr(args, "os_project_domain_id", "default") if not args.os_user_domain_id and not args.os_user_domain_name: setattr(args, "os_user_domain_id", "default") 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 = getattr(args, 'os_token', None) management_url = bypass_url if bypass_url else None if os_auth_system and os_auth_system != "keystone": warnings.warn( _('novaclient auth plugins that are not keystone are deprecated.' ' Auth plugins should now be done as plugins to keystoneauth' ' and selected with --os-auth-type or OS_AUTH_TYPE')) 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 skip_auth: 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([os_project_name, os_project_id]): 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]")) 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 = ( loading.load_session_from_argparse_arguments(args)) keystone_auth = ( loading.load_auth_from_argparse_arguments(args)) else: # set password for auth plugins os_password = args.os_password if (not skip_auth and not any([os_project_name, os_project_id])): 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 skip_auth: 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. self.cs = client.Client(api_versions.APIVersion("2.0"), os_username, os_password, os_project_name, tenant_id=os_project_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, logger=self.client_logger) if not skip_auth: 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, argv=argv) 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 = (utils.get_service_type(args.func) or DEFAULT_NOVA_SERVICE_TYPE) if utils.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 arguments. keystone_session = None keystone_auth = None # Recreate client object with discovered version. self.cs = client.Client(api_version, os_username, os_password, os_project_name, tenant_id=os_project_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 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 utils.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: raise exc.CommandError(_("Invalid OpenStack Nova credentials.")) except exc.AuthorizationFailure: raise exc.CommandError(_("Unable to authorize user")) args.func(self.cs, args) if args.timings: self._dump_timings(self.times + self.cs.get_timings())
def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser() (options, args) = parser.parse_known_args(argv) self.setup_debugging(options.debug) # build available subcommands based on version self.extensions = self._discover_extensions( options.os_compute_api_version) self._run_extension_hooks('__pre_parse_args__') # 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' subcommand_parser = self.get_subcommand_parser( options.os_compute_api_version) self.parser = subcommand_parser if options.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 (os_username, os_password, os_tenant_name, os_auth_url, os_region_name, os_auth_system, endpoint_type, insecure, service_type, service_name, volume_service_name, username, apikey, projectid, url, region_name, bypass_url, no_cache) = ( args.os_username, args.os_password, args.os_tenant_name, args.os_auth_url, args.os_region_name, args.os_auth_system, args.endpoint_type, args.insecure, args.service_type, args.service_name, args.volume_service_name, args.username, args.apikey, args.projectid, args.url, args.region_name, args.bypass_url, args.no_cache) if not endpoint_type: endpoint_type = DEFAULT_NOVA_ENDPOINT_TYPE if not service_type: service_type = DEFAULT_NOVA_SERVICE_TYPE service_type = utils.get_service_type(args.func) or service_type #FIXME(usrleon): Here should be restrict for project id same as # for os_username or os_password but for compatibility it is not. if not utils.isunauthenticated(args.func): if not os_username: if not username: raise exc.CommandError("You must provide a username " "via either --os-username or env[OS_USERNAME]") else: os_username = username if not os_password: if not apikey: raise exc.CommandError("You must provide a password " "via either --os-password or via " "env[OS_PASSWORD]") else: os_password = apikey if not os_tenant_name: if not projectid: raise exc.CommandError("You must provide a tenant name " "via either --os-tenant-name or " "env[OS_TENANT_NAME]") else: os_tenant_name = projectid if not os_auth_url: if not url: if os_auth_system and os_auth_system != 'keystone': os_auth_url = \ client.get_auth_system_url(os_auth_system) else: os_auth_url = 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") if not os_region_name and region_name: os_region_name = region_name if (options.os_compute_api_version and options.os_compute_api_version != '1.0'): if not os_tenant_name: raise exc.CommandError("You must provide a tenant name " "via either --os-tenant-name or env[OS_TENANT_NAME]") if not os_auth_url: raise exc.CommandError("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL]") self.cs = client.Client(options.os_compute_api_version, os_username, os_password, os_tenant_name, os_auth_url, 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, volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, no_cache=no_cache, http_log_debug=options.debug) try: if not utils.isunauthenticated(args.func): self.cs.authenticate() except exc.Unauthorized: raise exc.CommandError("Invalid OpenStack Nova credentials.") except exc.AuthorizationFailure: raise exc.CommandError("Unable to authorize user") args.func(self.cs, args) if args.timings: self._dump_timings(self.cs.get_timings())
def main(self, argv): # Parse args once to find version parser = self.get_base_parser() (options, args) = parser.parse_known_args(argv) self.setup_debugging(options.debug) # build available subcommands based on version self.extensions = self._discover_extensions(options.version) self._run_extension_hooks('__pre_parse_args__') subcommand_parser = self.get_subcommand_parser(options.version) self.parser = subcommand_parser if options.help and len(args) == 0: 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 (os_username, os_password, os_tenant_name, os_auth_url, os_region_name, endpoint_type, insecure, service_type, service_name, username, apikey, projectid, url, region_name) = ( args.os_username, args.os_password, args.os_tenant_name, args.os_auth_url, args.os_region_name, args.endpoint_type, args.insecure, args.service_type, args.service_name, args.username, args.apikey, args.projectid, args.url, args.region_name) if not endpoint_type: endpoint_type = DEFAULT_NOVA_ENDPOINT_TYPE if not service_type: service_type = DEFAULT_NOVA_SERVICE_TYPE service_type = utils.get_service_type(args.func) or service_type #FIXME(usrleon): Here should be restrict for project id same as # for os_username or os_password but for compatibility it is not. if not utils.isunauthenticated(args.func): if not os_username: if not username: raise exc.CommandError("You must provide a username " "via either --os_username or env[OS_USERNAME]") else: os_username = username if not os_password: if not apikey: raise exc.CommandError("You must provide a password " "via either --os_password or via " "env[OS_PASSWORD]") else: os_password = apikey if not os_tenant_name: if not projectid: raise exc.CommandError("You must provide a tenant name " "via either --os_tenant_name or " "env[OS_TENANT_NAME]") else: os_tenant_name = projectid if not os_auth_url: if not url: raise exc.CommandError("You must provide an auth url " "via either --os_auth_url or env[OS_AUTH_URL]") else: os_auth_url = url if not os_region_name and region_name: os_region_name = region_name if options.version and options.version != '1.0': if not os_tenant_name: raise exc.CommandError("You must provide a tenant name " "via either --os_tenant_name or env[OS_TENANT_NAME]") if not os_auth_url: raise exc.CommandError("You must provide an auth url " "via either --os_auth_url or env[OS_AUTH_URL]") self.cs = client.Client(options.version, os_username, os_password, os_tenant_name, os_auth_url, insecure, region_name=os_region_name, endpoint_type=endpoint_type, extensions=self.extensions, service_type=service_type, service_name=service_name) try: if not utils.isunauthenticated(args.func): self.cs.authenticate() except exc.Unauthorized: raise exc.CommandError("Invalid OpenStack Nova credentials.") except exc.AuthorizationFailure: raise exc.CommandError("Unable to authorize user") args.func(self.cs, args)
def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser(argv) # 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' # NOTE(Vek): Not emitting a warning here, as that will # occur when "--endpoint-type" is processed # For backwards compat with old os-auth-token parameter if '--os-auth-token' in argv: spot = argv.index('--os-auth-token') argv[spot] = '--os-token' print(_('WARNING: Option "%(option)s" is deprecated; %(use)s') % { 'option': '--os-auth-token', 'use': _('use "%s"; this option will be removed in ' 'novaclient 3.3.0.') % '--os-token', }, file=sys.stderr) (args, args_list) = parser.parse_known_args(argv) self.setup_debugging(args.debug) self.extensions = [] do_help = ('help' in argv) or ( '--help' in argv) or ('-h' in argv) or not argv # bash-completion should not require authentication skip_auth = do_help or ( 'bash-completion' in argv) # Discover available auth plugins 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_project_name = getattr( args, 'os_project_name', getattr(args, 'os_tenant_name', None)) os_project_id = getattr( args, 'os_project_id', getattr(args, 'os_tenant_id', None)) os_auth_url = args.os_auth_url os_region_name = args.os_region_name os_auth_system = args.os_auth_system if "v2.0" not in os_auth_url: # NOTE(andreykurilin): assume that keystone V3 is used and try to # be more user-friendly, i.e provide default values for domains if (not args.os_project_domain_id and not args.os_project_domain_name): setattr(args, "os_project_domain_id", "default") if not args.os_user_domain_id and not args.os_user_domain_name: setattr(args, "os_user_domain_id", "default") 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 = getattr(args, 'os_token', None) management_url = bypass_url if bypass_url else None if os_auth_system and os_auth_system != "keystone": warnings.warn(_( 'novaclient auth plugins that are not keystone are deprecated.' ' Auth plugins should now be done as plugins to keystoneauth' ' and selected with --os-auth-type or OS_AUTH_TYPE')) 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 skip_auth: 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([os_project_name, os_project_id]): 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]")) 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 = ( loading.load_session_from_argparse_arguments(args)) keystone_auth = ( loading.load_auth_from_argparse_arguments(args)) else: # set password for auth plugins os_password = args.os_password if (not skip_auth and not any([os_project_name, os_project_id])): 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 skip_auth: 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. self.cs = client.Client( api_versions.APIVersion("2.0"), os_username, os_password, os_project_name, tenant_id=os_project_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 skip_auth: 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, argv=argv) 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 = (utils.get_service_type(args.func) or DEFAULT_NOVA_SERVICE_TYPE) if utils.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 arguments. keystone_session = None keystone_auth = None # Recreate client object with discovered version. self.cs = client.Client( api_version, os_username, os_password, os_project_name, tenant_id=os_project_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 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 utils.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: raise exc.CommandError(_("Invalid OpenStack Nova credentials.")) except exc.AuthorizationFailure: raise exc.CommandError(_("Unable to authorize user")) args.func(self.cs, args) if args.timings: self._dump_timings(self.times + self.cs.get_timings())
def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser(argv) (args, args_list) = parser.parse_known_args(argv) self.setup_debugging(args.debug) self.extensions = [] do_help = args.help or not args_list or args_list[0] == 'help' # bash-completion should not require authentication skip_auth = do_help or ( 'bash-completion' in argv) 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) auth_token = getattr(args, "os_token", None) os_username = getattr(args, "os_username", None) os_user_id = getattr(args, "os_user_id", None) os_password = None # Fetched and set later as needed os_project_name = getattr( args, 'os_project_name', getattr(args, 'os_tenant_name', None)) os_project_id = getattr( args, 'os_project_id', getattr(args, 'os_tenant_id', None)) os_auth_url = args.os_auth_url os_region_name = args.os_region_name if "v2.0" not in os_auth_url: # NOTE(andreykurilin): assume that keystone V3 is used and try to # be more user-friendly, i.e provide default values for domains if (not args.os_project_domain_id and not args.os_project_domain_name): setattr(args, "os_project_domain_id", "default") # os_user_domain_id is redundant in case of Token auth type if not auth_token and (not args.os_user_domain_id and not args.os_user_domain_name): setattr(args, "os_user_domain_id", "default") os_project_domain_id = args.os_project_domain_id os_project_domain_name = args.os_project_domain_name os_user_domain_id = getattr(args, "os_user_domain_id", None) os_user_domain_name = getattr(args, "os_user_domain_name", None) endpoint_type = args.endpoint_type insecure = args.insecure service_type = args.service_type service_name = args.service_name endpoint_override = args.endpoint_override os_cache = args.os_cache cacert = args.os_cacert cert = args.os_cert timeout = args.timeout keystone_session = None keystone_auth = 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 # We should always auth unless we have a token and we're passing a # specific endpoint # Expired tokens are handled by client.py:_cs_request must_auth = not (auth_token and endpoint_override) # 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 skip_auth: if not any([auth_token, os_username, os_user_id]): raise exc.CommandError( _("You must provide a user name/id (via --os-username, " "--os-user-id, env[OS_USERNAME] or env[OS_USER_ID]) or " "an auth token (via --os-token).")) if not any([os_project_name, os_project_id]): 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: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL].")) # TODO(Shilpasd): need to provide support in python - novaclient # for required options for below default auth type plugins: # 1. v3oidcclientcredential # 2. v3oidcpassword # 3. v3oidcauthcode # 4. v3oidcaccesstoken # 5. v3oauth1 # 6. v3fedkerb # 7. v3adfspassword # 8. v3samlpassword # 9. v3applicationcredential # TODO(Shilpasd): need to provide support in python - novaclient # for below extra keystoneauth auth type plugins: # We will need to add code to support discovering of versions # supported by the keystone service based on the auth_url similar # to the one supported by glanceclient. # 1. v3password # 2. v3token # 3. v3kerberos # 4. v3totp with utils.record_time(self.times, args.timings, 'auth_url', args.os_auth_url): keystone_session = ( loading.load_session_from_argparse_arguments(args)) keystone_auth = ( loading.load_auth_from_argparse_arguments(args)) if (not skip_auth and not any([os_project_name, os_project_id])): 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 skip_auth: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL]")) additional_kwargs = {} if osprofiler_profiler: additional_kwargs["profile"] = args.profile # This client is just used to discover api version. Version API needn't # microversion, so we just pass version 2 at here. self.cs = client.Client( api_versions.APIVersion("2.0"), os_username, os_password, project_id=os_project_id, project_name=os_project_name, 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_token=auth_token, timings=args.timings, endpoint_override=endpoint_override, os_cache=os_cache, http_log_debug=args.debug, cacert=cacert, cert=cert, timeout=timeout, session=keystone_session, auth=keystone_auth, logger=self.client_logger, project_domain_id=os_project_domain_id, project_domain_name=os_project_domain_name, user_domain_id=os_user_domain_id, user_domain_name=os_user_domain_name, **additional_kwargs) if not skip_auth: 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, argv=argv) 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 = (utils.get_service_type(args.func) or DEFAULT_NOVA_SERVICE_TYPE) if utils.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 arguments. keystone_session = None keystone_auth = None # Recreate client object with discovered version. self.cs = client.Client( api_version, os_username, os_password, project_id=os_project_id, project_name=os_project_name, 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_token=auth_token, timings=args.timings, endpoint_override=endpoint_override, os_cache=os_cache, http_log_debug=args.debug, cacert=cacert, cert=cert, timeout=timeout, session=keystone_session, auth=keystone_auth, project_domain_id=os_project_domain_id, project_domain_name=os_project_domain_name, user_domain_id=os_user_domain_id, user_domain_name=os_user_domain_name) args.func(self.cs, args) if osprofiler_profiler and args.profile: trace_id = osprofiler_profiler.get().get_base_id() print("To display trace use the command:\n\n" " osprofiler trace show --html %s " % trace_id) if args.timings: self._dump_timings(self.times + self.cs.get_timings())
def main(self, argv): # Parse args once to find version parser = self.get_base_parser() (options, args) = parser.parse_known_args(argv) self.setup_debugging(options.debug) # build available subcommands based on version self.extensions = self._discover_extensions( options.os_compute_api_version) self._run_extension_hooks('__pre_parse_args__') subcommand_parser = self.get_subcommand_parser( options.os_compute_api_version) self.parser = subcommand_parser if options.help and len(args) == 0: 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 (os_username, os_password, os_tenant_name, os_auth_url, os_region_name, endpoint_type, insecure, service_type, service_name, volume_service_name, username, apikey, projectid, url, region_name) = ( args.os_username, args.os_password, args.os_tenant_name, args.os_auth_url, args.os_region_name, args.endpoint_type, args.insecure, args.service_type, args.service_name, args.volume_service_name, args.username, args.apikey, args.projectid, args.url, args.region_name) if not endpoint_type: endpoint_type = DEFAULT_NOVA_ENDPOINT_TYPE if not service_type: service_type = DEFAULT_NOVA_SERVICE_TYPE service_type = utils.get_service_type(args.func) or service_type #FIXME(usrleon): Here should be restrict for project id same as # for os_username or os_password but for compatibility it is not. if not utils.isunauthenticated(args.func): if not os_username: if not username: raise exc.CommandError("You must provide a username " "via either --os_username or env[OS_USERNAME]") else: os_username = username if not os_password: if not apikey: raise exc.CommandError("You must provide a password " "via either --os_password or via " "env[OS_PASSWORD]") else: os_password = apikey if not os_tenant_name: if not projectid: raise exc.CommandError("You must provide a tenant name " "via either --os_tenant_name or " "env[OS_TENANT_NAME]") else: os_tenant_name = projectid if not os_auth_url: if not url: raise exc.CommandError("You must provide an auth url " "via either --os_auth_url or env[OS_AUTH_URL]") else: os_auth_url = url if not os_region_name and region_name: os_region_name = region_name if (options.os_compute_api_version and options.os_compute_api_version != '1.0'): if not os_tenant_name: raise exc.CommandError("You must provide a tenant name " "via either --os_tenant_name or env[OS_TENANT_NAME]") if not os_auth_url: raise exc.CommandError("You must provide an auth url " "via either --os_auth_url or env[OS_AUTH_URL]") self.cs = client.Client(options.os_compute_api_version, os_username, os_password, os_tenant_name, os_auth_url, insecure, region_name=os_region_name, endpoint_type=endpoint_type, extensions=self.extensions, service_type=service_type, service_name=service_name, volume_service_name=volume_service_name) try: if not utils.isunauthenticated(args.func): self.cs.authenticate() except exc.Unauthorized: raise exc.CommandError("Invalid OpenStack Nova credentials.") except exc.AuthorizationFailure: raise exc.CommandError("Unable to authorize user") args.func(self.cs, args)
def main(self, argv): # Parse args once to find version and debug settings parser = self.get_base_parser(argv) (args, args_list) = parser.parse_known_args(argv) self.setup_debugging(args.debug) self.extensions = [] do_help = args.help or not args_list or args_list[0] == 'help' # bash-completion should not require authentication skip_auth = do_help or ('bash-completion' in argv) 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_project_name = getattr(args, 'os_project_name', getattr(args, 'os_tenant_name', None)) os_project_id = getattr(args, 'os_project_id', getattr(args, 'os_tenant_id', None)) os_auth_url = args.os_auth_url os_region_name = args.os_region_name if "v2.0" not in os_auth_url: # NOTE(andreykurilin): assume that keystone V3 is used and try to # be more user-friendly, i.e provide default values for domains if (not args.os_project_domain_id and not args.os_project_domain_name): setattr(args, "os_project_domain_id", "default") if not args.os_user_domain_id and not args.os_user_domain_name: setattr(args, "os_user_domain_id", "default") os_project_domain_id = args.os_project_domain_id os_project_domain_name = args.os_project_domain_name os_user_domain_id = args.os_project_domain_id os_user_domain_name = args.os_project_domain_name endpoint_type = args.endpoint_type insecure = args.insecure service_type = args.service_type service_name = args.service_name endpoint_override = args.endpoint_override os_cache = args.os_cache cacert = args.os_cacert cert = args.os_cert 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 = getattr(args, 'os_token', 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 # We should always auth unless we have a token and we're passing a # specific endpoint # Expired tokens are handled by client.py:_cs_request must_auth = not (auth_token and endpoint_override) # 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 skip_auth: 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([os_project_name, os_project_id]): 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: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL].")) with utils.record_time(self.times, args.timings, 'auth_url', args.os_auth_url): keystone_session = ( loading.load_session_from_argparse_arguments(args)) keystone_auth = ( loading.load_auth_from_argparse_arguments(args)) if (not skip_auth and not any([os_project_name, os_project_id])): 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 skip_auth: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL]")) additional_kwargs = {} if osprofiler_profiler: additional_kwargs["profile"] = args.profile # This client is just used to discover api version. Version API needn't # microversion, so we just pass version 2 at here. self.cs = client.Client(api_versions.APIVersion("2.0"), os_username, os_password, project_id=os_project_id, project_name=os_project_name, 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_token=auth_token, timings=args.timings, endpoint_override=endpoint_override, os_cache=os_cache, http_log_debug=args.debug, cacert=cacert, cert=cert, timeout=timeout, session=keystone_session, auth=keystone_auth, logger=self.client_logger, project_domain_id=os_project_domain_id, project_domain_name=os_project_domain_name, user_domain_id=os_user_domain_id, user_domain_name=os_user_domain_name, **additional_kwargs) if not skip_auth: 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, argv=argv) 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 = (utils.get_service_type(args.func) or DEFAULT_NOVA_SERVICE_TYPE) if utils.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 arguments. keystone_session = None keystone_auth = None # Recreate client object with discovered version. self.cs = client.Client(api_version, os_username, os_password, os_project_name, tenant_id=os_project_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_token=auth_token, timings=args.timings, endpoint_override=endpoint_override, os_cache=os_cache, http_log_debug=args.debug, cacert=cacert, cert=cert, timeout=timeout, session=keystone_session, auth=keystone_auth, project_domain_id=os_project_domain_id, project_domain_name=os_project_domain_name, user_domain_id=os_user_domain_id, user_domain_name=os_user_domain_name) # Now check for the password/token of which pieces of the # identifying keyring key can come from the underlying client if must_auth: helper = SecretsHelper(args, self.cs.client) self.cs.client.keyring_saver = helper tenant_id = helper.tenant_id # Allow commandline to override cache if not auth_token: auth_token = helper.auth_token endpoint_override = endpoint_override or helper.management_url if tenant_id and auth_token and endpoint_override: self.cs.client.tenant_id = tenant_id self.cs.client.auth_token = auth_token self.cs.client.management_url = endpoint_override self.cs.client.password_func = lambda: helper.password else: # We're missing something, so auth with user/pass and save # the result in our helper. self.cs.client.password = helper.password args.func(self.cs, args) if osprofiler_profiler and args.profile: trace_id = osprofiler_profiler.get().get_base_id() print("To display trace use the command:\n\n" " osprofiler trace show --html %s " % trace_id) if args.timings: self._dump_timings(self.times + self.cs.get_timings())