def load_from_argparse_arguments(cls, namespace, **kwargs): token = kwargs.get('token') or namespace.os_token endpoint = kwargs.get('endpoint') or namespace.os_endpoint auth_url = kwargs.get('auth_url') or namespace.os_auth_url if token and not endpoint: # if a user provides a token then they must also provide an # endpoint because we aren't fetching a token to get a catalog from msg = _('A service URL must be provided with a token') raise exc.CommandError(msg) elif (not token) and (not auth_url): # if you don't provide a token you are going to provide at least an # auth_url with which to authenticate. raise exc.CommandError( _('Expecting an auth URL via either ' '--os-auth-url or env[OS_AUTH_URL]')) plugin = super(DefaultCLI, cls).load_from_argparse_arguments(namespace, **kwargs) if (not token) and (not plugin._password): # we do this after the load so that the base plugin has an # opportunity to prompt the user for a password raise exc.CommandError( _('Expecting a password provided via ' 'either --os-password, env[OS_PASSWORD], ' 'or prompted response')) return plugin
def find_resource(manager, name_or_id): """Helper for the _find_* methods.""" # first try to get entity as integer id try: if isinstance(name_or_id, int) or name_or_id.isdigit(): return manager.get(int(name_or_id)) except exceptions.NotFound: pass # now try the entity as a string try: return manager.get(name_or_id) except (exceptions.NotFound): pass # finally try to find entity by name try: if isinstance(name_or_id, six.binary_type): name_or_id = name_or_id.decode('utf-8', 'strict') return manager.find(name=name_or_id) except exceptions.NotFound: msg = ("No %s with a name or ID of '%s' exists." % (manager.resource_class.__name__.lower(), name_or_id)) raise exceptions.CommandError(msg) except exceptions.NoUniqueMatch: msg = ("Multiple %s matches found for '%s', use an ID to be more" " specific." % (manager.resource_class.__name__.lower(), name_or_id)) raise exceptions.CommandError(msg)
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 subcommand_parser = self.get_subcommand_parser(options.version) self.parser = subcommand_parser # Parse args again and call whatever callback was selected args = subcommand_parser.parse_args(argv) # Deal with global arguments if args.debug: httplib2.debuglevel = 1 # Short-circuit and deal with help right away. if args.func == self.do_help: self.do_help(args) return 0 #FIXME(usrleon): Here should be restrict for project id same as # for username or apikey but for compatibility it is not. if not utils.isunauthenticated(args.func): if not args.username: raise exc.CommandError( "You must provide a username " "via either --username or env[OS_USERNAME]") if not args.password: raise exc.CommandError( "You must provide a password " "via either --password or env[OS_PASSWORD]") if not args.auth_url: raise exc.CommandError( "You must provide an auth url " "via either --auth_url or via env[OS_AUTH_URL]") if utils.isunauthenticated(args.func): self.cs = shell_generic.CLIENT_CLASS(endpoint=args.auth_url) else: self.cs = self.get_api_class(options.version)( username=args.username, tenant_name=args.tenant_name, tenant_id=args.tenant_id, password=args.password, auth_url=args.auth_url, region_name=args.region_name) try: if not utils.isunauthenticated(args.func): self.cs.authenticate() except exc.Unauthorized: raise exc.CommandError("Invalid OpenStack Keystone credentials.") except exc.AuthorizationFailure: raise exc.CommandError("Unable to authorize user") args.func(self.cs, args)
def create(self, name, user=None, secret=None, description=None, expires_at=None, roles=None, unrestricted=False, **kwargs): """Create a credential. :param string name: application credential name :param string user: User ID :param secret: application credential secret :param description: application credential description :param datetime.datetime expires_at: expiry time :param List roles: list of roles on the project. Maybe a list of IDs or a list of dicts specifying role name and domain :param bool unrestricted: whether the application credential has restrictions applied :returns: the created application credential :rtype: :class:`keystoneclient.v3.application_credentials.ApplicationCredential` """ user = user or self.client.user_id self.base_url = '/users/%(user)s' % {'user': user} # Convert roles list into list-of-dict API format role_list = [] if roles: if not isinstance(roles, list): roles = [roles] for role in roles: if isinstance(role, six.string_types): role_list.extend([{'id': role}]) elif isinstance(role, dict): role_list.extend([role]) else: msg = (_("Roles must be a list of IDs or role dicts.")) raise exceptions.CommandError(msg) if not role_list: role_list = None # Convert datetime.datetime expires_at to iso format string if expires_at: expires_str = utils.isotime(at=expires_at, subsecond=True) else: expires_str = None return super(ApplicationCredentialManager, self).create(name=name, secret=secret, description=description, expires_at=expires_str, roles=role_list, unrestricted=unrestricted, **kwargs)
def do_help(self, args): """Display help about this program or one of its subcommands.""" if getattr(args, 'command', None): if args.command in self.subcommands: self.subcommands[args.command].print_help() else: raise exc.CommandError("'%s' is not a valid subcommand" % args.command) else: self.parser.print_help()
def find_resource(manager, name_or_id): """Helper for the _find_* methods.""" # first try the entity as a string try: return manager.get(name_or_id) except (ksa_exceptions.NotFound): # nosec(cjschaef): try to find # 'name_or_id' as a six.binary_type instead pass # finally try to find entity by name try: if isinstance(name_or_id, six.binary_type): name_or_id = name_or_id.decode('utf-8', 'strict') return manager.find(name=name_or_id) except ksa_exceptions.NotFound: msg = ("No %s with a name or ID of '%s' exists." % (manager.resource_class.__name__.lower(), name_or_id)) raise ksc_exceptions.CommandError(msg) except ksc_exceptions.NoUniqueMatch: msg = ("Multiple %s matches found for '%s', use an ID to be more" " specific." % (manager.resource_class.__name__.lower(), name_or_id)) raise ksc_exceptions.CommandError(msg)
def auth_check(self, args): if args.os_token or args.os_endpoint: if not args.os_token: raise exc.CommandError( 'Expecting a token provided via either --os-token or ' 'env[OS_SERVICE_TOKEN]') if not args.os_endpoint: raise exc.CommandError( 'Expecting an endpoint provided via either ' '--os-endpoint or env[OS_SERVICE_ENDPOINT]') # user supplied a token and endpoint and at least one other cred if args.os_username or args.os_password or args.os_auth_url: msg = ('WARNING: Bypassing authentication using a token & ' 'endpoint (authentication credentials are being ' 'ignored).') print(msg) else: if not args.os_auth_url: raise exc.CommandError( 'Expecting an auth URL via either --os-auth-url or ' 'env[OS_AUTH_URL]') if args.os_username or args.os_password: if not args.os_username: raise exc.CommandError( 'Expecting a username provided via either ' '--os-username or env[OS_USERNAME]') if not args.os_password: # No password, If we've got a tty, try prompting for it if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty(): # Check for Ctl-D try: args.os_password = getpass.getpass('OS Password: '******'t have a tty or the # user Ctl-D when prompted? if not args.os_password: raise exc.CommandError( 'Expecting a password provided via either ' '--os-password, env[OS_PASSWORD], or ' 'prompted response') else: raise exc.CommandError('Expecting authentication method via' '\n either a service token, ' '--os-token or env[OS_SERVICE_TOKEN], ' '\n credentials, ' '--os-username or env[OS_USERNAME]')
def auth_check(self, args): if args.os_token or args.os_endpoint: if not args.os_token: raise exc.CommandError( 'Expecting a token provided via either --os-token or ' 'env[OS_SERVICE_TOKEN]') if not args.os_endpoint: raise exc.CommandError( 'Expecting an endpoint provided via either ' '--os-endpoint or env[OS_SERVICE_ENDPOINT]') # user supplied a token and endpoint and at least one other cred if args.os_username or args.os_password or args.os_auth_url: msg = ('WARNING: Bypassing authentication using a token & ' 'endpoint (authentication credentials are being ' 'ignored).') print(msg) else: if not args.os_auth_url: raise exc.CommandError( 'Expecting an auth URL via either --os-auth-url or ' 'env[OS_AUTH_URL]') if args.os_username or args.os_password: if not args.os_username: raise exc.CommandError( 'Expecting a username provided via either ' '--os-username or env[OS_USERNAME]') if not args.os_password: args.os_password = utils.prompt_user_password() # No password because we didn't have a tty or the # user Ctl-D when prompted? if not args.os_password: raise exc.CommandError( 'Expecting a password provided via either ' '--os-password, env[OS_PASSWORD], or ' 'prompted response') else: raise exc.CommandError('Expecting authentication method via' '\n either a service token, ' '--os-token or env[OS_SERVICE_TOKEN], ' '\n credentials, ' '--os-username or env[OS_USERNAME]')
def find_resource(manager, name_or_id): """Helper for the _find_* methods.""" # first try to get entity as integer id try: if isinstance(name_or_id, int) or name_or_id.isdigit(): return manager.get(int(name_or_id)) except exceptions.NotFound: pass # now try to get entity as uuid try: uuid.UUID(str(name_or_id)) return manager.get(name_or_id) except (ValueError, exceptions.NotFound): pass # finally try to find entity by name try: return manager.find(name=name_or_id) except exceptions.NotFound: msg = ("No %s with a name or ID of '%s' exists." % (manager.resource_class.__name__.lower(), name_or_id)) raise exceptions.CommandError(msg)
def error(self, message): raise exceptions.CommandError(message)
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) # Deal with global arguments if args.debug: httplib2.debuglevel = 1 # Short-circuit and deal with help command right away. if args.func == self.do_help: self.do_help(args) return 0 #FIXME(usrleon): Here should be restrict for project id same as # for username or apikey but for compatibility it is not. # provide support for legacy args args.os_username = args.os_username or args.username args.os_password = args.os_password or args.password args.os_auth_url = args.os_auth_url or args.auth_url args.os_tenant_name = args.os_tenant_name or args.tenant_name args.os_region_name = args.os_region_name or args.region_name if not utils.isunauthenticated(args.func): # if the user hasn't provided any auth data if not (args.token or args.endpoint or args.os_username or args.os_password or args.os_auth_url): raise exc.CommandError('Expecting authentication method via \n' ' either a service token, ' '--token or env[SERVICE_TOKEN], \n' ' or credentials, ' '--os_username or env[OS_USERNAME].') # if it looks like the user wants to provide a service token # but is missing something if args.token or args.endpoint and not (args.token and args.endpoint): if not args.token: raise exc.CommandError( 'Expecting a token provided ' 'via either --token or env[SERVICE_TOKEN]') if not args.endpoint: raise exc.CommandError( 'Expecting an endpoint provided ' 'via either --endpoint or env[SERVICE_ENDPOINT]') # if it looks like the user wants to provide a credentials # but is missing something if ((args.os_username or args.os_password or args.os_auth_url) and not (args.os_username and args.os_password and args.os_auth_url)): if not args.os_username: raise exc.CommandError( 'Expecting a username provided ' 'via either --os_username or env[OS_USERNAME]') if not args.os_password: raise exc.CommandError( 'Expecting a password provided ' 'via either --os_password or env[OS_PASSWORD]') if not args.os_auth_url: raise exc.CommandError( 'Expecting an auth URL ' 'via either --os_auth_url or env[OS_AUTH_URL]') if utils.isunauthenticated(args.func): self.cs = shell_generic.CLIENT_CLASS(endpoint=args.os_auth_url) else: token = None endpoint = None if args.token and args.endpoint: token = args.token endpoint = args.endpoint 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=endpoint, password=args.os_password, auth_url=args.os_auth_url, region_name=args.os_region_name) try: args.func(self.cs, args) except exc.Unauthorized: raise exc.CommandError("Invalid OpenStack Identity credentials.") except exc.AuthorizationFailure: raise exc.CommandError("Unable to authorize user")
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: args.func(self.cs, args) except exc.Unauthorized: raise exc.CommandError("Invalid OpenStack Identity credentials.") except exc.AuthorizationFailure: raise exc.CommandError("Unable to authorize user")
def find_attr( self, path, value=None, attr=None, resource=None, ): """Find a resource via attribute or ID Most APIs return a list wrapped by a dict with the resource name as key. Some APIs (Identity) return a dict when a query string is present and there is one return value. Take steps to unwrap these bodies and return a single dict without any resource wrappers. :param string path: The API-specific portion of the URL path :param string value: value to search for :param string attr: attribute to use for resource search :param string resource: plural of the object resource name; defaults to path For example: n = find(netclient, 'network', 'networks', 'matrix') """ # Default attr is 'name' if attr is None: attr = 'name' # Default resource is path - in many APIs they are the same if resource is None: resource = path def getlist(kw): """Do list call, unwrap resource dict if present""" ret = self.list(path, **kw) if type(ret) == dict and resource in ret: ret = ret[resource] return ret # Search by attribute kwargs = {attr: value} data = getlist(kwargs) if type(data) == dict: return data if len(data) == 1: return data[0] if len(data) > 1: msg = "Multiple %s exist with %s='%s'" raise ksc_exceptions.CommandError(msg % (resource, attr, value), ) # Search by id kwargs = {'id': value} data = getlist(kwargs) if len(data) == 1: return data[0] msg = "No %s with a %s or ID of '%s' found" raise exceptions.CommandError(msg % (resource, attr, value))
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) # Deal with global arguments if args.debug: httplib2.debuglevel = 1 # 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 #FIXME(usrleon): Here should be restrict for project id same as # for username or apikey but for compatibility it is not. # 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 not utils.isunauthenticated(args.func): # if the user hasn't provided any auth data if not (args.os_token or args.os_endpoint or args.os_username or args.os_password or args.os_auth_url): raise exc.CommandError('Expecting authentication method via \n' ' either a service token, ' '--token or env[SERVICE_TOKEN], \n' ' or credentials, ' '--os-username or env[OS_USERNAME].') # if it looks like the user wants to provide a service token # but is missing something if args.os_token or args.os_endpoint and not (args.os_token and args.os_endpoint): if not args.os_token: raise exc.CommandError( 'Expecting a token provided via either --token or ' 'env[SERVICE_TOKEN]') if not args.os_endpoint: raise exc.CommandError( 'Expecting an endpoint provided via either --endpoint ' 'or env[SERVICE_ENDPOINT]') # if it looks like the user wants to provide a credentials # but is missing something if ((args.os_username or args.os_password or args.os_auth_url) and not (args.os_username and args.os_password and args.os_auth_url)): if not args.os_username: raise exc.CommandError( 'Expecting a username provided via either ' '--os-username or env[OS_USERNAME]') if not args.os_password: # No password, If we've got a tty, try prompting for it if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty(): # Check for Ctl-D try: args.os_password = getpass.getpass('OS Password: '******'t have a tty or the # user Ctl-D when prompted? if not args.os_password: raise exc.CommandError( 'Expecting a password provided via either ' '--os-password, env[OS_PASSWORD], or ' 'prompted response') if not args.os_auth_url: raise exc.CommandError( 'Expecting an auth URL via either --os-auth-url or ' 'env[OS_AUTH_URL]') 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) else: token = None endpoint = None if args.os_token and args.os_endpoint: token = args.os_token endpoint = args.os_endpoint 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=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) try: args.func(self.cs, args) except exc.Unauthorized: raise exc.CommandError("Invalid OpenStack Identity credentials.") except exc.AuthorizationFailure: raise exc.CommandError("Unable to authorize user")