Exemple #1
0
def format_labels(lbls, parse_comma=True):
    '''Reformat labels into dict of format expected by the API.'''

    if not lbls:
        return {}

    if parse_comma:
        # expect multiple invocations of --labels but fall back
        # to , delimited if only one --labels is specified
        if len(lbls) == 1:
            lbls = lbls[0].split(',')

    labels = {}
    for l in lbls:
        try:
            (k, v) = l.split(('='), 1)
        except ValueError:
            raise exc.CommandError(
                _('labels must be a list of KEY=VALUE '
                  'not %s') % l)
        if k not in labels:
            labels[k] = v
        else:
            if not isinstance(labels[k], list):
                labels[k] = [labels[k]]
            labels[k].append(v)

    return labels
 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()
Exemple #3
0
    def do_help(self, args):
        """Display help about this program or one of its subcommands."""
        # NOTE(jamespage): args.command is not guaranteed with python >= 3.4
        command = getattr(args, 'command', '')

        if 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()
Exemple #4
0
def args_array_to_patch(op, attributes):
    patch = []
    for attr in attributes:
        # Sanitize
        if not attr.startswith('/'):
            attr = '/' + attr
        if op in ['add', 'replace']:
            path, value = split_and_deserialize(attr)
            patch.append({'op': op, 'path': path, 'value': value})

        elif op == "remove":
            # For remove only the key is needed
            patch.append({'op': op, 'path': attr})
        else:
            raise exc.CommandError(_('Unknown PATCH operation: %s') % op)
    return patch
Exemple #5
0
def split_and_deserialize(string):
    """Split and try to JSON deserialize a string.

    Gets a string with the KEY=VALUE format, split it (using '=' as the
    separator) and try to JSON deserialize the VALUE.
    :returns: A tuple of (key, value).
    """
    try:
        key, value = string.split("=", 1)
    except ValueError:
        raise exc.CommandError(
            _('Attributes must be a list of '
              'PATH=VALUE not "%s"') % string)
    try:
        value = json.loads(value)
    except ValueError:
        pass

    return (key, value)
Exemple #6
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)

        # 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.magnum_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.
        # NOTE(jamespage): args.func is not guaranteed with python >= 3.4
        if not hasattr(args, 'func') or 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_tenant_id, os_auth_url,
         os_auth_system, endpoint_type, service_type,
         bypass_url) = ((args.os_username, args.os_tenant_name,
                         args.os_tenant_id, args.os_auth_url,
                         args.os_auth_system, args.endpoint_type,
                         args.service_type, args.bypass_url))

        if os_auth_system and os_auth_system != "keystone":
            auth_plugin = auth.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_ENDPOINT_TYPE

        if not service_type:
            service_type = DEFAULT_SERVICE_TYPE
# NA - there is only one service this CLI accesses
#            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 cliutils.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 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]")

# NOTE: The Magnum client authenticates when you create it. So instead of
#       creating here and authenticating later, which is what the novaclient
#       does, we just create the client later.

# Now check for the password/token of which pieces of the
# identifying keyring key can come from the underlying client
        if not cliutils.isunauthenticated(args.func):
            # NA - Client can't be used with SecretsHelper
            if (auth_plugin and auth_plugin.opts
                    and "os_password" not in auth_plugin.opts):
                use_pw = False
            else:
                use_pw = True

            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 = args.os_password
                if not os_password:
                    raise exc.CommandError(
                        'Expecting a password provided via either '
                        '--os-password, env[OS_PASSWORD], or '
                        'prompted response')

        try:
            client = {
                '1': client_v1,
            }[options.magnum_api_version]
        except KeyError:
            client = client_v1

        self.cs = client.Client(username=os_username,
                                api_key=os_password,
                                project_id=os_tenant_id,
                                project_name=os_tenant_name,
                                auth_url=os_auth_url,
                                service_type=service_type,
                                region_name=args.os_region_name,
                                magnum_url=bypass_url)

        args.func(self.cs, args)
Exemple #7
0
def find_resource(manager, name_or_id, **find_args):
    """Look for resource in a given manager.

    Used as a helper for the _find_* methods.
    Example:

    .. code-block:: python

        def _find_hypervisor(cs, hypervisor):
            #Get a hypervisor by name or ID.
            return cliutils.find_resource(cs.hypervisors, hypervisor)
    """
    # first 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:
        if six.PY2:
            tmp_id = encodeutils.safe_encode(name_or_id)
        else:
            tmp_id = encodeutils.safe_decode(name_or_id)

        if uuidutils.is_uuid_like(tmp_id):
            return manager.get(tmp_id)
    except (TypeError, ValueError, exceptions.NotFound):
        pass

    # for str id which is not uuid
    if getattr(manager, 'is_alphanum_id_allowed', False):
        try:
            return manager.get(name_or_id)
        except exceptions.NotFound:
            pass

    try:
        try:
            return manager.find(human_id=name_or_id, **find_args)
        except exceptions.NotFound:
            pass

        # 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 %(name)s with a name or "
                    "ID of '%(name_or_id)s' exists.") % \
                {
                    "name": manager.resource_class.__name__.lower(),
                    "name_or_id": name_or_id
                }
            raise exceptions.CommandError(msg)
    except exceptions.NoUniqueMatch:
        msg = _("Multiple %(name)s matches found for "
                "'%(name_or_id)s', use an ID to be more specific.") % \
            {
                "name": manager.resource_class.__name__.lower(),
                "name_or_id": name_or_id
            }
        raise exceptions.CommandError(msg)