Exemplo n.º 1
0
def positive_non_zero_float(text):
    if text is None:
        return None
    try:
        value = float(text)
    except ValueError:
        msg = _("%s must be a float") % text
        raise argparse.ArgumentTypeError(msg)
    if value <= 0:
        msg = _("%s must be greater than 0") % text
        raise argparse.ArgumentTypeError(msg)
    return value
Exemplo n.º 2
0
def positive_non_zero_float(text):
    if text is None:
        return None
    try:
        value = float(text)
    except ValueError:
        msg = _("%s must be a float") % text
        raise argparse.ArgumentTypeError(msg)
    if value <= 0:
        msg = _("%s must be greater than 0") % text
        raise argparse.ArgumentTypeError(msg)
    return value
Exemplo n.º 3
0
def find_resource(manager, name_or_id, **find_args):
    """Helper for the _find_* methods."""
    # for str id which is not uuid (for Flavor and Keypair search currently)
    if getattr(manager, 'is_alphanum_id_allowed', False):
        try:
            return manager.get(name_or_id)
        except exceptions.NotFound:
            pass

    # try to get entity as integer id
    try:
        return manager.get(int(name_or_id))
    except (TypeError, ValueError, exceptions.NotFound):
        pass

    # now try to get entity as uuid
    try:
        tmp_id = encodeutils.safe_encode(name_or_id)

        if six.PY3:
            tmp_id = tmp_id.decode()

        uuid.UUID(tmp_id)
        return manager.get(tmp_id)
    except (TypeError, ValueError, exceptions.NotFound):
        pass

    try:
        # finally try to find entity by name
        try:
            resource = getattr(manager, 'resource_class', None)
            name_attr = resource.NAME_ATTR if resource else 'name'
            kwargs = {name_attr: name_or_id}
            kwargs.update(find_args)
            return manager.find(**kwargs)
        except exceptions.NotFound:
            msg = (_("No %(class)s with a name or ID of '%(name)s' exists.") %
                   {
                       'class': manager.resource_class.__name__.lower(),
                       'name': name_or_id
                   })
            raise exceptions.CommandError(msg)
    except exceptions.NoUniqueMatch:
        msg = (_("Multiple %(class)s matches found for '%(name)s', use an ID "
                 "to be more specific.") % {
                     'class': manager.resource_class.__name__.lower(),
                     'name': name_or_id
                 })
        raise exceptions.CommandError(msg)
Exemplo n.º 4
0
def validate_flavor_metadata_keys(keys):
    for key in keys:
        valid_name = VALID_KEY_REGEX.match(key)
        if not valid_name:
            msg = _('Invalid key: "%s". Keys may only contain letters, '
                    'numbers, spaces, underscores, periods, colons and '
                    'hyphens.')
            raise exceptions.CommandError(msg % key)
Exemplo n.º 5
0
def find_resource(manager, name_or_id, **find_args):
    """Helper for the _find_* methods."""
    # for str id which is not uuid (for Flavor and Keypair search currently)
    if getattr(manager, 'is_alphanum_id_allowed', False):
        try:
            return manager.get(name_or_id)
        except exceptions.NotFound:
            pass

    # try to get entity as integer id
    try:
        return manager.get(int(name_or_id))
    except (TypeError, ValueError, exceptions.NotFound):
        pass

    # now try to get entity as uuid
    try:
        tmp_id = encodeutils.safe_encode(name_or_id)

        if six.PY3:
            tmp_id = tmp_id.decode()

        uuid.UUID(tmp_id)
        return manager.get(tmp_id)
    except (TypeError, ValueError, exceptions.NotFound):
        pass

    try:
        # finally try to find entity by name
        try:
            resource = getattr(manager, 'resource_class', None)
            name_attr = resource.NAME_ATTR if resource else 'name'
            kwargs = {name_attr: name_or_id}
            kwargs.update(find_args)
            return manager.find(**kwargs)
        except exceptions.NotFound:
            msg = (_("No %(class)s with a name or ID of '%(name)s' exists.") %
                   {'class': manager.resource_class.__name__.lower(),
                    'name': name_or_id})
            raise exceptions.CommandError(msg)
    except exceptions.NoUniqueMatch:
        msg = (_("Multiple %(class)s matches found for '%(name)s', use an ID "
                 "to be more specific.") %
               {'class': manager.resource_class.__name__.lower(),
                'name': name_or_id})
        raise exceptions.CommandError(msg)
Exemplo n.º 6
0
def validate_flavor_metadata_keys(keys):
    for key in keys:
        valid_name = VALID_KEY_REGEX.match(key)
        if not valid_name:
            msg = _('Invalid key: "%s". Keys may only contain letters, '
                    'numbers, spaces, underscores, periods, colons and '
                    'hyphens.')
            raise exceptions.CommandError(msg % key)
Exemplo n.º 7
0
 def do_help(self, args):
     """
     Display help about this program or one of its subcommands.
     """
     if args.command:
         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()
Exemplo n.º 8
0
 def do_help(self, args):
     """
     Display help about this program or one of its subcommands.
     """
     if args.command:
         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()
Exemplo n.º 9
0
    def _extract_service_catalog(self, url, resp, body, extract_token=True):
        """See what the auth service told us and process the response.
        We may get redirected to another site, fail or actually get
        back a service catalog with a token and our endpoints.
        """

        # content must always present
        if resp.status_code == 200 or resp.status_code == 201:
            try:
                self.auth_url = url
                self.service_catalog = \
                    service_catalog.ServiceCatalog(body)
                if extract_token:
                    self.auth_token = self.service_catalog.get_token()
                    self.tenant_id = self.service_catalog.get_tenant_id()

                management_url = self.service_catalog.url_for(
                    attr='region',
                    filter_value=self.region_name,
                    endpoint_type=self.endpoint_type,
                    service_type=self.service_type,
                    service_name=self.service_name,
                    volume_service_name=self.volume_service_name,)
                self.management_url = management_url.rstrip('/')
                return None
            except exceptions.AmbiguousEndpoints:
                print(_("Found more than one valid endpoint. Use a more "
                      "restrictive filter"))
                raise
            except KeyError:
                raise exceptions.AuthorizationFailure()
            except exceptions.EndpointNotFound:
                print(_("Could not find any suitable endpoint. Correct "
                        "region?"))
                raise

        elif resp.status_code == 305:
            return resp.headers['location']
        else:
            raise exceptions.from_response(resp, body, url)
Exemplo n.º 10
0
def get_client_class(version):
    version_map = {
        '1.0': 'fsgatewayclient.v1_0.client.Client',
    }
    try:
        client_path = version_map[str(version)]
    except (KeyError, ValueError):
        msg = _("Invalid client version '%(version)s'. must be one of: "
                "%(keys)s") % {'version': version,
                               'keys': ', '.join(version_map.keys())}
        raise exceptions.UnsupportedVersion(msg)

    return importutils.import_class(client_path)
Exemplo n.º 11
0
 def save(self, auth_token, management_url, tenant_id):
     if not HAS_KEYRING or not self.args.os_cache:
         return
     if (auth_token == self.auth_token and
             management_url == self.management_url):
         # Nothing changed....
         return
     if not all([management_url, auth_token, tenant_id]):
         raise ValueError(_("Unable to save empty management url/auth "
                            "token"))
     value = "|".join([str(auth_token),
                       str(management_url),
                       str(tenant_id)])
     keyring.set_password("fs_gatewayclient_auth", self._make_key(), value)
Exemplo n.º 12
0
    def error(self, message):
        """error(message: string)

        Prints a usage message incorporating the message to stderr and
        exits.
        """
        self.print_usage(sys.stderr)
        # FIXME(lzyeval): if changes occur in argparse.ArgParser._check_value
        choose_from = ' (choose from'
        progparts = self.prog.partition(' ')
        self.exit(2, _("error: %(errmsg)s\nTry '%(mainp)s help %(subp)s'"
                     " for more information.\n") %
                     {'errmsg': message.split(choose_from)[0],
                      'mainp': progparts[0],
                      'subp': progparts[2]})
Exemplo n.º 13
0
 def save(self, auth_token, management_url, tenant_id):
     if not HAS_KEYRING or not self.args.os_cache:
         return
     if (auth_token == self.auth_token
             and management_url == self.management_url):
         # Nothing changed....
         return
     if not all([management_url, auth_token, tenant_id]):
         raise ValueError(
             _("Unable to save empty management url/auth "
               "token"))
     value = "|".join(
         [str(auth_token),
          str(management_url),
          str(tenant_id)])
     keyring.set_password("fs_gatewayclient_auth", self._make_key(), value)
Exemplo n.º 14
0
def get_resource_manager_extra_kwargs(f, args, allow_conflicts=False):
    """Return extra_kwargs by calling resource manager kwargs hooks."""
    hooks = getattr(f, "resource_manager_kwargs_hooks", [])
    extra_kwargs = {}
    for hook in hooks:
        hook_kwargs = hook(args)
        hook_name = hook.__name__
        conflicting_keys = set(hook_kwargs.keys()) & set(extra_kwargs.keys())
        if conflicting_keys and not allow_conflicts:
            msg = (_("Hook '%(hook_name)s' is attempting to redefine "
                     "attributes '%(conflicting_keys)s'") %
                   {'hook_name': hook_name,
                    'conflicting_keys': conflicting_keys})
            raise exceptions.NoUniqueMatch(msg)

        extra_kwargs.update(hook_kwargs)

    return extra_kwargs
Exemplo n.º 15
0
    def error(self, message):
        """error(message: string)

        Prints a usage message incorporating the message to stderr and
        exits.
        """
        self.print_usage(sys.stderr)
        # FIXME(lzyeval): if changes occur in argparse.ArgParser._check_value
        choose_from = ' (choose from'
        progparts = self.prog.partition(' ')
        self.exit(
            2,
            _("error: %(errmsg)s\nTry '%(mainp)s help %(subp)s'"
              " for more information.\n") % {
                  'errmsg': message.split(choose_from)[0],
                  'mainp': progparts[0],
                  'subp': progparts[2]
              })
Exemplo n.º 16
0
def get_resource_manager_extra_kwargs(f, args, allow_conflicts=False):
    """Return extra_kwargs by calling resource manager kwargs hooks."""
    hooks = getattr(f, "resource_manager_kwargs_hooks", [])
    extra_kwargs = {}
    for hook in hooks:
        hook_kwargs = hook(args)
        hook_name = hook.__name__
        conflicting_keys = set(hook_kwargs.keys()) & set(extra_kwargs.keys())
        if conflicting_keys and not allow_conflicts:
            msg = (_("Hook '%(hook_name)s' is attempting to redefine "
                     "attributes '%(conflicting_keys)s'") % {
                         'hook_name': hook_name,
                         'conflicting_keys': conflicting_keys
                     })
            raise exceptions.NoUniqueMatch(msg)

        extra_kwargs.update(hook_kwargs)

    return extra_kwargs
Exemplo n.º 17
0
    """Get a user by name, ID."""
    try:
        return utils.find_resource(cs.users, user)
    except exceptions.NotFound as e:
        raise e


def do_user_list(cs, args):
    """Print a list of available 'users'."""
    users = cs.users.list()
    _print_user_list(users)


@utils.arg('user',
    metavar='<user>',
    help=_("Name or ID of the user to delete"))
def do_user_delete(cs, args):
    """Delete a specific user"""
    userid = _find_user(cs, args.user)
    cs.users.delete(userid)
    _print_user_list([userid])


@utils.arg('user',
     metavar='<user>',
     help=_("Name or ID of user"))
def do_user_show(cs, args):
    """Show details about the given user."""
    user = _find_user(cs, args.user)
    _print_user(user)
Exemplo n.º 18
0
    def get_base_parser(self):
        parser = FS_GatewayClientArgumentParser(
            prog='fsgateway',
            description=__doc__.strip(),
            epilog='See "fsgateway help COMMAND" '
                   'for help on a specific command.',
            add_help=False,
            formatter_class=OpenStackHelpFormatter,
        )

        # Global arguments
        parser.add_argument('-h', '--help',
            action='store_true',
            help=argparse.SUPPRESS,
        )

        parser.add_argument('--version',
                            action='version',
                            version=fsgatewayclient.__version__)

        parser.add_argument('--debug',
            default=False,
            action='store_true',
            help=_("Print debugging output"))

        parser.add_argument('--os-cache',
            default=strutils.bool_from_string(
                utils.env('OS_CACHE', default=False), True),
            action='store_true',
            help=_("Use the auth token cache. Defaults to False if "
                   "env[OS_CACHE] is not set."))

        parser.add_argument('--timings',
            default=False,
            action='store_true',
            help=_("Print call timing info"))

        parser.add_argument('--os-auth-token',
                default=utils.env('OS_AUTH_TOKEN'),
                help='Defaults to env[OS_AUTH_TOKEN]')

        parser.add_argument('--os-username',
            metavar='<auth-user-name>',
            default=utils.env('OS_USERNAME', 'FS_GATEWAY_USERNAME'),
            help=_('Defaults to env[OS_USERNAME].'))
        parser.add_argument('--os_username',
            help=argparse.SUPPRESS)

        parser.add_argument('--os-user-id',
            metavar='<auth-user-id>',
            default=utils.env('OS_USER_ID'),
            help=_('Defaults to env[OS_USER_ID].'))

        parser.add_argument('--os-password',
            metavar='<auth-password>',
            default=utils.env('OS_PASSWORD', 'FS_GATEWAY_PASSWORD'),
            help=_('Defaults to env[OS_PASSWORD].'))
        parser.add_argument('--os_password',
            help=argparse.SUPPRESS)

        parser.add_argument('--os-tenant-name',
            metavar='<auth-tenant-name>',
            default=utils.env('OS_TENANT_NAME', 'FS_GATEWAY_PROJECT_ID'),
            help=_('Defaults to env[OS_TENANT_NAME].'))
        parser.add_argument('--os_tenant_name',
            help=argparse.SUPPRESS)

        parser.add_argument('--os-tenant-id',
            metavar='<auth-tenant-id>',
            default=utils.env('OS_TENANT_ID'),
            help=_('Defaults to env[OS_TENANT_ID].'))

        parser.add_argument('--os-auth-url',
            metavar='<auth-url>',
            default=utils.env('OS_AUTH_URL', 'FS_GATEWAY_URL'),
            help=_('Defaults to env[OS_AUTH_URL].'))
        parser.add_argument('--os_auth_url',
            help=argparse.SUPPRESS)

        parser.add_argument('--os-auth-system',
            metavar='<auth-system>',
            default=utils.env('OS_AUTH_SYSTEM'),
            help='Defaults to env[OS_AUTH_SYSTEM].')
        parser.add_argument('--os_auth_system',
            help=argparse.SUPPRESS)

        parser.add_argument('--os-compute-api-version',
            metavar='<compute-api-ver>',
            default=utils.env('OS_COMPUTE_API_VERSION',
                default=DEFAULT_OS_COMPUTE_API_VERSION),
            help=_('Accepts 1.0 or 3, '
                 'defaults to env[OS_COMPUTE_API_VERSION].'))
        parser.add_argument('--os_compute_api_version',
            help=argparse.SUPPRESS)

        parser.add_argument('--bypass-url',
            metavar='<bypass-url>',
            dest='bypass_url',
            default=utils.env('FS_GATEWAYCLIENT_BYPASS_URL'),
            help="Use this API endpoint instead of the Service Catalog. "
                 "Defaults to env[FS_GATEWAYCLIENT_BYPASS_URL]")
        parser.add_argument('--bypass_url',
            help=argparse.SUPPRESS)

        # The auth-system-plugins might require some extra options
        fsgatewayclient.auth_plugin.load_auth_system_opts(parser)

        self._append_global_identity_args(parser)

        return parser
Exemplo n.º 19
0
    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
        fsgatewayclient.auth_plugin.discover_auth_systems()

        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)

        # 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_auth_system = args.os_auth_system
        insecure = args.insecure
        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 = fsgatewayclient.auth_plugin.load_plugin(os_auth_system)
        else:
            auth_plugin = None

        # 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.
        must_auth = None
        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]"))

        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,
                 auth_system=os_auth_system,
                auth_plugin=auth_plugin, auth_token=auth_token,
                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()
                pass
        except exc.Unauthorized:
            raise exc.CommandError(_("Invalid OpenStack FS_Gateway 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())
Exemplo n.º 20
0
    def get_base_parser(self):
        parser = FS_GatewayClientArgumentParser(
            prog='fsgateway',
            description=__doc__.strip(),
            epilog='See "fsgateway help COMMAND" '
            'for help on a specific command.',
            add_help=False,
            formatter_class=OpenStackHelpFormatter,
        )

        # Global arguments
        parser.add_argument(
            '-h',
            '--help',
            action='store_true',
            help=argparse.SUPPRESS,
        )

        parser.add_argument('--version',
                            action='version',
                            version=fsgatewayclient.__version__)

        parser.add_argument('--debug',
                            default=False,
                            action='store_true',
                            help=_("Print debugging output"))

        parser.add_argument(
            '--os-cache',
            default=strutils.bool_from_string(
                utils.env('OS_CACHE', default=False), True),
            action='store_true',
            help=_("Use the auth token cache. Defaults to False if "
                   "env[OS_CACHE] is not set."))

        parser.add_argument('--timings',
                            default=False,
                            action='store_true',
                            help=_("Print call timing info"))

        parser.add_argument('--os-auth-token',
                            default=utils.env('OS_AUTH_TOKEN'),
                            help='Defaults to env[OS_AUTH_TOKEN]')

        parser.add_argument('--os-username',
                            metavar='<auth-user-name>',
                            default=utils.env('OS_USERNAME',
                                              'FS_GATEWAY_USERNAME'),
                            help=_('Defaults to env[OS_USERNAME].'))
        parser.add_argument('--os_username', help=argparse.SUPPRESS)

        parser.add_argument('--os-user-id',
                            metavar='<auth-user-id>',
                            default=utils.env('OS_USER_ID'),
                            help=_('Defaults to env[OS_USER_ID].'))

        parser.add_argument('--os-password',
                            metavar='<auth-password>',
                            default=utils.env('OS_PASSWORD',
                                              'FS_GATEWAY_PASSWORD'),
                            help=_('Defaults to env[OS_PASSWORD].'))
        parser.add_argument('--os_password', help=argparse.SUPPRESS)

        parser.add_argument('--os-tenant-name',
                            metavar='<auth-tenant-name>',
                            default=utils.env('OS_TENANT_NAME',
                                              'FS_GATEWAY_PROJECT_ID'),
                            help=_('Defaults to env[OS_TENANT_NAME].'))
        parser.add_argument('--os_tenant_name', help=argparse.SUPPRESS)

        parser.add_argument('--os-tenant-id',
                            metavar='<auth-tenant-id>',
                            default=utils.env('OS_TENANT_ID'),
                            help=_('Defaults to env[OS_TENANT_ID].'))

        parser.add_argument('--os-auth-url',
                            metavar='<auth-url>',
                            default=utils.env('OS_AUTH_URL', 'FS_GATEWAY_URL'),
                            help=_('Defaults to env[OS_AUTH_URL].'))
        parser.add_argument('--os_auth_url', help=argparse.SUPPRESS)

        parser.add_argument('--os-auth-system',
                            metavar='<auth-system>',
                            default=utils.env('OS_AUTH_SYSTEM'),
                            help='Defaults to env[OS_AUTH_SYSTEM].')
        parser.add_argument('--os_auth_system', help=argparse.SUPPRESS)

        parser.add_argument('--os-compute-api-version',
                            metavar='<compute-api-ver>',
                            default=utils.env(
                                'OS_COMPUTE_API_VERSION',
                                default=DEFAULT_OS_COMPUTE_API_VERSION),
                            help=_('Accepts 1.0 or 3, '
                                   'defaults to env[OS_COMPUTE_API_VERSION].'))
        parser.add_argument('--os_compute_api_version', help=argparse.SUPPRESS)

        parser.add_argument(
            '--bypass-url',
            metavar='<bypass-url>',
            dest='bypass_url',
            default=utils.env('FS_GATEWAYCLIENT_BYPASS_URL'),
            help="Use this API endpoint instead of the Service Catalog. "
            "Defaults to env[FS_GATEWAYCLIENT_BYPASS_URL]")
        parser.add_argument('--bypass_url', help=argparse.SUPPRESS)

        # The auth-system-plugins might require some extra options
        fsgatewayclient.auth_plugin.load_auth_system_opts(parser)

        self._append_global_identity_args(parser)

        return parser
Exemplo n.º 21
0
    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
        fsgatewayclient.auth_plugin.discover_auth_systems()

        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)

        # 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_auth_system = args.os_auth_system
        insecure = args.insecure
        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 = fsgatewayclient.auth_plugin.load_plugin(
                os_auth_system)
        else:
            auth_plugin = None

        # 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.
        must_auth = None
        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]"))

        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,
                                auth_system=os_auth_system,
                                auth_plugin=auth_plugin,
                                auth_token=auth_token,
                                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()
                pass
        except exc.Unauthorized:
            raise exc.CommandError(
                _("Invalid OpenStack FS_Gateway 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())