Exemplo n.º 1
0
def common_params_for_list(args, fields, field_labels):
    params = {}
    if args.marker is not None:
        params['marker'] = args.marker
    if args.limit is not None:
        params['limit'] = args.limit

    if args.sort_key is not None:
        # Support using both heading and field name for sort_key
        fields_map = dict(zip(field_labels, fields))
        fields_map.update(zip(fields, fields))
        try:
            sort_key = fields_map[args.sort_key]
        except KeyError:
            raise exc.CommandError(
                _("%(sort_key)s is not a valid field for sorting, "
                  "valid are %(valid)s") % {
                      'sort_key': args.sort_key,
                      'valid': list(fields_map)
                  })
        params['sort_key'] = sort_key
    if args.sort_dir is not None:
        if args.sort_dir not in ('asc', 'desc'):
            raise exc.CommandError(
                _("%s is not valid value for sort direction, "
                  "valid are 'asc' and 'desc'") % args.sort_dir)
        params['sort_dir'] = args.sort_dir

    params['detail'] = args.detail

    return params
Exemplo n.º 2
0
    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
        api_version = options.ironic_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 options.help or not argv:
            self.do_help(options)
            return 0
        elif argv[0] == 'bash-completion':
            self._bash_completion()
            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

        if not (args.os_auth_token and args.ironic_url):
            if not args.os_username:
                raise exc.CommandError(
                    _("You must provide a username via "
                      "either --os-username or via "
                      "env[OS_USERNAME]"))

            if not args.os_password:
                raise exc.CommandError(
                    _("You must provide a password via "
                      "either --os-password or via "
                      "env[OS_PASSWORD]"))

            if not (args.os_tenant_id or args.os_tenant_name):
                raise exc.CommandError(
                    _("You must provide a tenant_id via "
                      "either --os-tenant-id or via "
                      "env[OS_TENANT_ID]"))

            if not args.os_auth_url:
                raise exc.CommandError(
                    _("You must provide an auth url via "
                      "either --os-auth-url or via "
                      "env[OS_AUTH_URL]"))

        client = iroclient.get_client(api_version, **(args.__dict__))

        try:
            args.func(client, args)
        except exc.Unauthorized:
            raise exc.CommandError(_("Invalid OpenStack Identity credentials"))
Exemplo n.º 3
0
    def _check_version(self, api_version):
        """Validate the supplied API (micro)version.

        :param api_version: API version as a string ("1", "1.x" or "latest")
        :returns: tuple (major version, version string)
        """
        if api_version in ('1', 'latest'):
            return (1, LATEST_VERSION)
        else:
            try:
                versions = tuple(int(i) for i in api_version.split('.'))
            except ValueError:
                versions = ()

            if not versions or len(versions) > 2:
                msg = _("The requested API version %(ver)s is an unexpected "
                        "format. Acceptable formats are 'X', 'X.Y', or the "
                        "literal string 'latest'.") % {
                            'ver': api_version
                        }
                raise exc.CommandError(msg)

            if versions == (1, 0):
                os_ironic_api_version = None
            else:
                os_ironic_api_version = api_version

            api_major_version = versions[0]
            return (api_major_version, os_ironic_api_version)
Exemplo n.º 4
0
    def _discover_auth_versions(self, session, auth_url):
        # discover the API versions the server is supporting base on the
        # given URL
        v2_auth_url = None
        v3_auth_url = None
        try:
            ks_discover = discover.Discover(session=session, auth_url=auth_url)
            v2_auth_url = ks_discover.url_for('2.0')
            v3_auth_url = ks_discover.url_for('3.0')
        except ks_exc.ClientException:
            # Identity service may not support discover API version.
            # Let's try to figure out the API version from the original URL.
            url_parts = urlparse.urlparse(auth_url)
            (scheme, netloc, path, params, query, fragment) = url_parts
            path = path.lower()
            if path.startswith('/v3'):
                v3_auth_url = auth_url
            elif path.startswith('/v2'):
                v2_auth_url = auth_url
            else:
                # not enough information to determine the auth version
                msg = _('Unable to determine the Keystone version '
                        'to authenticate with using the given '
                        'auth_url. Identity service may not support API '
                        'version discovery. Please provide a versioned '
                        'auth_url instead. %s') % auth_url
                raise exc.CommandError(msg)

        return (v2_auth_url, v3_auth_url)
    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)
        client = self.app.client_manager.baremetal

        params = {}
        if parsed_args.limit is not None and parsed_args.limit < 0:
            raise exc.CommandError(
                _('Expected non-negative --limit, got %s') % parsed_args.limit)
        params['limit'] = parsed_args.limit
        params['marker'] = parsed_args.marker
        for field in ('node', 'resource_class', 'state', 'owner'):
            value = getattr(parsed_args, field)
            if value is not None:
                params[field] = value

        if parsed_args.long:
            columns = res_fields.ALLOCATION_DETAILED_RESOURCE.fields
            labels = res_fields.ALLOCATION_DETAILED_RESOURCE.labels
        elif parsed_args.fields:
            fields = itertools.chain.from_iterable(parsed_args.fields)
            resource = res_fields.Resource(list(fields))
            columns = resource.fields
            labels = resource.labels
            params['fields'] = columns
        else:
            columns = res_fields.ALLOCATION_RESOURCE.fields
            labels = res_fields.ALLOCATION_RESOURCE.labels

        self.log.debug("params(%s)", params)
        data = client.allocation.list(**params)

        data = oscutils.sort_items(data, parsed_args.sort)

        return (labels, (oscutils.get_item_properties(s, columns)
                         for s in data))
Exemplo n.º 6
0
def do_node_set_power_state(cc, args):
    """Power a node on or off or reboot."""
    try:
        cc.node.set_power_state(args.node, args.power_state, args.soft,
                                timeout=args.power_timeout)
    except ValueError as e:
        raise exc.CommandError(six.text_type(e))
Exemplo n.º 7
0
    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)" % parsed_args)
        client = self.app.client_manager.baremetal

        columns = res_fields.NODE_RESOURCE

        params = {}
        if parsed_args.limit is not None and parsed_args.limit < 0:
            raise exc.CommandError(
                _('Expected non-negative --limit, got %s') % parsed_args.limit)
        params['limit'] = parsed_args.limit
        params['marker'] = parsed_args.marker
        if parsed_args.associated:
            params['associated'] = parsed_args.associated
        if parsed_args.maintenance:
            params['maintenance'] = parsed_args.maintenance

        if parsed_args.long:
            columns = res_fields.NODE_DETAILED_RESOURCE
        params['detail'] = parsed_args.long

        self.log.debug("params(%s)" % params)
        data = client.node.list(**params)

        data = oscutils.sort_items(data, parsed_args.sort)

        return (columns.labels, (oscutils.get_item_properties(
            s,
            columns.fields,
            formatters={'Properties': oscutils.format_dict},
        ) for s in data))
Exemplo n.º 8
0
def bool_argument_value(arg_name, bool_str, strict=True, default=False):
    """Returns the Boolean represented by bool_str.

    Returns the Boolean value for the argument named arg_name. The value is
    represented by the string bool_str. If the string is an invalid Boolean
    string: if strict is True, a CommandError exception is raised; otherwise
    the default value is returned.

    :param arg_name: The name of the argument
    :param bool_str: The string representing a Boolean value
    :param strict: Used if the string is invalid. If True, raises an exception.
        If False, returns the default value.
    :param default: The default value to return if the string is invalid
        and not strict
    :returns: the Boolean value represented by bool_str or the default value
        if bool_str is invalid and strict is False
    :raises CommandError: if bool_str is an invalid Boolean string

    """
    try:
        val = strutils.bool_from_string(bool_str, strict, default)
    except ValueError as e:
        raise exc.CommandError(_("argument %(arg)s: %(err)s.")
                               % {'arg': arg_name, 'err': e})
    return val
    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)" % parsed_args)
        client = self.app.client_manager.baremetal

        columns = res_fields.CHASSIS_RESOURCE.fields
        labels = res_fields.CHASSIS_RESOURCE.labels

        params = {}
        if parsed_args.limit is not None and parsed_args.limit < 0:
            raise exc.CommandError(
                _('Expected non-negative --limit, got %s') % parsed_args.limit)
        params['limit'] = parsed_args.limit
        params['marker'] = parsed_args.marker
        if parsed_args.long:
            params['detail'] = parsed_args.long
            columns = res_fields.CHASSIS_DETAILED_RESOURCE.fields
            labels = res_fields.CHASSIS_DETAILED_RESOURCE.labels
        elif parsed_args.fields:
            params['detail'] = False
            fields = itertools.chain.from_iterable(parsed_args.fields)
            resource = res_fields.Resource(list(fields))
            columns = resource.fields
            labels = resource.labels
            params['fields'] = columns

        self.log.debug("params(%s)" % params)
        data = client.chassis.list(**params)

        data = oscutils.sort_items(data, parsed_args.sort)

        return (labels, (oscutils.get_item_properties(
            s,
            columns,
            formatters={'Properties': oscutils.format_dict},
        ) for s in data))
Exemplo n.º 10
0
    def _check_version(self, api_version):
        if api_version == 'latest':
            return LATEST_API_VERSION
        else:
            try:
                versions = tuple(int(i) for i in api_version.split('.'))
            except ValueError:
                versions = ()
            if len(versions) == 1:
                # Default value of ironic_api_version is '1'.
                # If user not specify the value of api version, not passing
                # headers at all.
                os_ironic_api_version = None
            elif len(versions) == 2:
                os_ironic_api_version = api_version
                # In the case of '1.0'
                if versions[1] == 0:
                    os_ironic_api_version = None
            else:
                msg = _("The requested API version %(ver)s is an unexpected "
                        "format. Acceptable formats are 'X', 'X.Y', or the "
                        "literal string '%(latest)s'."
                        ) % {'ver': api_version, 'latest': 'latest'}
                raise exc.CommandError(msg)

            api_major_version = versions[0]
            return (api_major_version, os_ironic_api_version)
Exemplo n.º 11
0
def common_params_for_list(args, fields, field_labels):
    """Generate 'params' dict that is common for every 'list' command.

    :param args: arguments from command line.
    :param fields: possible fields for sorting.
    :param field_labels: possible field labels for sorting.
    :returns: a dict with params to pass to the client method.
    """
    params = {}
    if args.marker is not None:
        params['marker'] = args.marker
    if args.limit is not None:
        if args.limit < 0:
            raise exc.CommandError(
                _('Expected non-negative --limit, got %s') % args.limit)
        params['limit'] = args.limit

    if args.sort_key is not None:
        # Support using both heading and field name for sort_key
        fields_map = dict(zip(field_labels, fields))
        fields_map.update(zip(fields, fields))
        try:
            sort_key = fields_map[args.sort_key]
        except KeyError:
            raise exc.CommandError(
                _("%(sort_key)s is an invalid field for sorting, "
                  "valid values for --sort-key are: %(valid)s") % {
                      'sort_key': args.sort_key,
                      'valid': list(fields_map)
                  })
        params['sort_key'] = sort_key
    if args.sort_dir is not None:
        if args.sort_dir not in ('asc', 'desc'):
            raise exc.CommandError(
                _("%s is an invalid value for sort direction, "
                  "valid values for --sort-dir are: 'asc', 'desc'") %
                args.sort_dir)
        params['sort_dir'] = args.sort_dir

    params['detail'] = args.detail

    requested_fields = args.fields[0] if args.fields else None
    if requested_fields is not None:
        params['fields'] = requested_fields

    return params
Exemplo n.º 12
0
def make_configdrive(path):
    """Make the config drive file.

    :param path: The directory containing the config drive files.
    :returns: A gzipped and base64 encoded configdrive string.

    """
    # Make sure path it's readable
    if not os.access(path, os.R_OK):
        raise exc.CommandError(_('The directory "%s" is not readable') % path)

    with tempfile.NamedTemporaryFile() as tmpfile:
        with tempfile.NamedTemporaryFile() as tmpzipfile:
            publisher = 'ironicclient-configdrive 0.1'
            try:
                p = subprocess.Popen(['genisoimage', '-o', tmpfile.name,
                                      '-ldots', '-allow-lowercase',
                                      '-allow-multidot', '-l',
                                      '-publisher', publisher,
                                      '-quiet', '-J',
                                      '-r', '-V', 'config-2',
                                      path],
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)
            except OSError as e:
                raise exc.CommandError(
                    _('Error generating the config drive. Make sure the '
                      '"genisoimage" tool is installed. Error: %s') % e)

            stdout, stderr = p.communicate()
            if p.returncode != 0:
                raise exc.CommandError(
                    _('Error generating the config drive.'
                      'Stdout: "%(stdout)s". Stderr: %(stderr)s') %
                    {'stdout': stdout, 'stderr': stderr})

            # Compress file
            tmpfile.seek(0)
            g = gzip.GzipFile(fileobj=tmpzipfile, mode='wb')
            shutil.copyfileobj(tmpfile, g)
            g.close()

            tmpzipfile.seek(0)
            return base64.b64encode(tmpzipfile.read())
Exemplo n.º 13
0
 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()
Exemplo n.º 14
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']:
            try:
                path, value = attr.split("=", 1)
                patch.append({'op': op, 'path': path, 'value': value})
            except ValueError:
                raise exc.CommandError(
                    _('Attributes must be a list of '
                      'PATH=VALUE not "%s"') % attr)
        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
Exemplo n.º 15
0
def args_array_to_dict(kwargs, key_to_convert):
    values_to_convert = kwargs.get(key_to_convert)
    if values_to_convert:
        try:
            kwargs[key_to_convert] = dict(
                v.split("=", 1) for v in values_to_convert)
        except ValueError:
            raise exc.CommandError(
                _('%(key)s must be a list of KEY=VALUE not "%(values)s"') % {
                    'key': key_to_convert,
                    'values': values_to_convert
                })
    return kwargs
Exemplo n.º 16
0
def check_for_invalid_fields(fields, valid_fields):
    """Check for invalid fields.

    :param fields: A list of fields specified by the user.
    :param valid_fields: A list of valid fields.
    :raises CommandError: If invalid fields were specified by the user.
    """
    if not fields:
        return

    invalid_fields = set(fields) - set(valid_fields)
    if invalid_fields:
        raise exc.CommandError(
            _('Invalid field(s) requested: %(invalid)s. Valid fields '
              'are: %(valid)s.') % {'invalid': ', '.join(invalid_fields),
                                    'valid': ', '.join(valid_fields)})
Exemplo n.º 17
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
Exemplo n.º 18
0
    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        baremetal_client = self.app.client_manager.baremetal

        if parsed_args.boot_index is not None and parsed_args.boot_index < 0:
            raise exc.CommandError(
                _('Expected non-negative --boot-index, got %s') %
                parsed_args.boot_index)

        properties = []
        if parsed_args.node_uuid:
            properties.extend(
                utils.args_array_to_patch(
                    'add', ["node_uuid=%s" % parsed_args.node_uuid]))
        if parsed_args.volume_type:
            properties.extend(
                utils.args_array_to_patch(
                    'add', ["volume_type=%s" % parsed_args.volume_type]))
        if parsed_args.boot_index:
            properties.extend(
                utils.args_array_to_patch(
                    'add', ["boot_index=%s" % parsed_args.boot_index]))
        if parsed_args.volume_id:
            properties.extend(
                utils.args_array_to_patch(
                    'add', ["volume_id=%s" % parsed_args.volume_id]))

        if parsed_args.properties:
            properties.extend(
                utils.args_array_to_patch(
                    'add',
                    ["properties/" + x for x in parsed_args.properties]))
        if parsed_args.extra:
            properties.extend(
                utils.args_array_to_patch(
                    'add', ["extra/" + x for x in parsed_args.extra]))

        if properties:
            baremetal_client.volume_target.update(parsed_args.volume_target,
                                                  properties)
        else:
            self.log.warning("Please specify what to set.")
Exemplo n.º 19
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)
Exemplo n.º 20
0
    def _get_keystone_auth(self, session, auth_url, **kwargs):
        # FIXME(dhu): this code should come from keystoneclient

        # discover the supported keystone versions using the given url
        (v2_auth_url, v3_auth_url) = self._discover_auth_versions(
            session=session,
            auth_url=auth_url)

        # Determine which authentication plugin to use. First inspect the
        # auth_url to see the supported version. If both v3 and v2 are
        # supported, then use the highest version if possible.
        auth = None
        if v3_auth_url and v2_auth_url:
            user_domain_name = kwargs.get('user_domain_name', None)
            user_domain_id = kwargs.get('user_domain_id', None)
            project_domain_name = kwargs.get('project_domain_name', None)
            project_domain_id = kwargs.get('project_domain_id', None)

            # support both v2 and v3 auth. Use v3 if domain information is
            # provided.
            if (user_domain_name or user_domain_id or project_domain_name or
                    project_domain_id):
                auth = self._get_keystone_v3_auth(v3_auth_url, **kwargs)
            else:
                auth = self._get_keystone_v2_auth(v2_auth_url, **kwargs)
        elif v3_auth_url:
            # support only v3
            auth = self._get_keystone_v3_auth(v3_auth_url, **kwargs)
        elif v2_auth_url:
            # support only v2
            auth = self._get_keystone_v2_auth(v2_auth_url, **kwargs)
        else:
            msg = _('Unable to determine the Keystone version '
                    'to authenticate with using the given '
                    'auth_url.')
            raise exc.CommandError(msg)

        return auth
Exemplo n.º 21
0
    def take_action(self, parsed_args):
        super(ProvisionStateWithWait, self).take_action(parsed_args)
        self.log.debug("take_action(%s)", parsed_args)

        if (parsed_args.wait_timeout is None):
            return

        baremetal_client = self.app.client_manager.baremetal
        wait_args = v1_utils.PROVISION_ACTIONS.get(
            parsed_args.provision_state)
        if wait_args is None:
            # This should never happen in reality, but checking just in case
            raise exc.CommandError(
                _("'--wait is not supported for provision state '%s'")
                % parsed_args.provision_state)

        print(_('Waiting for provision state %(state)s on node %(node)s') %
              {'state': wait_args['expected_state'], 'node': parsed_args.node})

        baremetal_client.node.wait_for_provision_state(
            parsed_args.node,
            timeout=parsed_args.wait_timeout,
            **wait_args)
Exemplo n.º 22
0
    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)" % parsed_args)
        baremetal_client = self.app.client_manager.baremetal

        if parsed_args.boot_index < 0:
            raise exc.CommandError(
                _('Expected non-negative --boot-index, got %s') %
                parsed_args.boot_index)

        field_list = [
            'extra', 'volume_type', 'properties', 'boot_index', 'node_uuid',
            'volume_id', 'uuid'
        ]
        fields = dict((k, v) for (k, v) in vars(parsed_args).items()
                      if k in field_list and v is not None)
        fields = utils.args_array_to_dict(fields, 'properties')
        fields = utils.args_array_to_dict(fields, 'extra')
        volume_target = baremetal_client.volume_target.create(**fields)

        data = dict([(f, getattr(volume_target, f, ''))
                     for f in res_fields.VOLUME_TARGET_DETAILED_RESOURCE.fields
                     ])
        return self.dict2columns(data)
Exemplo n.º 23
0
    def main(self, argv):
        # TODO(rloo): delete the ironic CLI in the S* cycle.
        print(
            'The "ironic" CLI is deprecated and will be removed in the '
            'S* release. Please use the "openstack baremetal" CLI instead.',
            file=sys.stderr)
        # 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
        (api_major_version, os_ironic_api_version) = (self._check_version(
            options.ironic_api_version))

        subcommand_parser = self.get_subcommand_parser(api_major_version)
        self.parser = subcommand_parser

        # Handle top-level --help/-h before attempting to parse
        # a command off the command line
        if options.help or not argv:
            self.do_help(options)
            return 0

        # Parse args again and call whatever callback was selected
        args = subcommand_parser.parse_args(argv)

        # Short-circuit and deal with these commands 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()
            return 0

        # Assume password auth if it does not seem like none, admin_token or
        # token auth
        if not args.endpoint and not (args.token and args.auth_url):
            if not args.username:
                raise exc.CommandError(
                    _("You must provide a username via "
                      "either --os-username or via "
                      "env[OS_USERNAME]"))

            if not args.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.password = getpass.getpass('OpenStack Password: '******'t have a tty or the
            # user Ctl-D when prompted.
            if not args.password:
                raise exc.CommandError(
                    _("You must provide a password via "
                      "either --os-password, "
                      "env[OS_PASSWORD], "
                      "or prompted response"))

            if not (args.tenant_id or args.tenant_name or args.project_id
                    or args.project_name):
                raise exc.CommandError(
                    _("You must provide a project name or"
                      " project id via --os-project-name, --os-project-id,"
                      " env[OS_PROJECT_ID] or env[OS_PROJECT_NAME]."))

            if not args.auth_url:
                raise exc.CommandError(
                    _("You must provide an auth url via "
                      "either --os-auth-url or via "
                      "env[OS_AUTH_URL]"))

        if args.max_retries < 0:
            raise exc.CommandError(
                _("You must provide value >= 0 for "
                  "--max-retries"))
        if args.retry_interval < 1:
            raise exc.CommandError(
                _("You must provide value >= 1 for "
                  "--retry-interval"))
        client_args = ('token', 'endpoint', 'username', 'password', 'auth_url',
                       'project_id', 'project_name', 'tenant_id',
                       'tenant_name', 'region_name', 'user_domain_id',
                       'user_domain_name', 'project_domain_id',
                       'project_domain_name', 'service_type', 'interface',
                       'max_retries', 'retry_interval', 'timeout', 'insecure')
        kwargs = {}
        for key in client_args:
            value = getattr(args, key)
            # NOTE(vdrok): check for both None and ''. If the default value
            # for option is set using cliutils.env function, default empty
            # value is ''. If the default is not set explicitly, it is None.
            if value not in (None, ''):
                kwargs[key] = value
        # NOTE(vdrok): this is to workaround the fact that these options are
        # named differently in keystoneauth, depending on whether they are
        # provided through CLI or loaded from conf options, here we unify them.
        for cli_ssl_opt, conf_ssl_opt in [('os_cacert', 'cafile'),
                                          ('os_cert', 'certfile'),
                                          ('os_key', 'keyfile')]:
            value = getattr(args, cli_ssl_opt)
            if value not in (None, ''):
                kwargs[conf_ssl_opt] = value
        kwargs['os_ironic_api_version'] = os_ironic_api_version
        client = ironicclient.client.get_client(api_major_version, **kwargs)
        if options.ironic_api_version in ('1', 'latest'):
            # Allow negotiating a lower version, if the latest version
            # supported by the client is higher than the latest version
            # supported by the server.
            client.http_client.api_version_select_state = 'default'

        try:
            args.func(client, args)
        except exc.Unauthorized:
            raise exc.CommandError(_("Invalid OpenStack Identity credentials"))
        except exc.CommandError as e:
            subcommand_parser = self.subcommands[args.subparser_name]
            subcommand_parser.error(e)
Exemplo n.º 24
0
    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
        (api_major_version, os_ironic_api_version) = (self._check_version(
            options.ironic_api_version))

        subcommand_parser = self.get_subcommand_parser(api_major_version)
        self.parser = subcommand_parser

        # Handle top-level --help/-h before attempting to parse
        # a command off the command line
        if options.help or not argv:
            self.do_help(options)
            return 0

        # Parse args again and call whatever callback was selected
        args = subcommand_parser.parse_args(argv)

        # Short-circuit and deal with these commands 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()
            return 0

        if not (args.os_auth_token and (args.ironic_url or args.os_auth_url)):
            if not args.os_username:
                raise exc.CommandError(
                    _("You must provide a username via "
                      "either --os-username or via "
                      "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(
                            'OpenStack Password: '******'t have a tty or the
            # user Ctl-D when prompted.
            if not args.os_password:
                raise exc.CommandError(
                    _("You must provide a password via "
                      "either --os-password, "
                      "env[OS_PASSWORD], "
                      "or prompted response"))

            if not (args.os_tenant_id or args.os_tenant_name
                    or args.os_project_id or args.os_project_name):
                raise exc.CommandError(
                    _("You must provide a project name or"
                      " project id via --os-project-name, --os-project-id,"
                      " env[OS_PROJECT_ID] or env[OS_PROJECT_NAME].  You may"
                      " use os-project and os-tenant interchangeably."))

            if not args.os_auth_url:
                raise exc.CommandError(
                    _("You must provide an auth url via "
                      "either --os-auth-url or via "
                      "env[OS_AUTH_URL]"))

        if args.max_retries < 0:
            raise exc.CommandError(
                _("You must provide value >= 0 for "
                  "--max-retries"))
        if args.retry_interval < 1:
            raise exc.CommandError(
                _("You must provide value >= 1 for "
                  "--retry-interval"))
        client_args = ('os_auth_token', 'ironic_url', 'os_username',
                       'os_password', 'os_auth_url', 'os_project_id',
                       'os_project_name', 'os_tenant_id', 'os_tenant_name',
                       'os_region_name', 'os_user_domain_id',
                       'os_user_domain_name', 'os_project_domain_id',
                       'os_project_domain_name', 'os_service_type',
                       'os_endpoint_type', 'os_cacert', 'os_cert', 'os_key',
                       'max_retries', 'retry_interval', 'timeout', 'insecure')
        kwargs = {}
        for key in client_args:
            kwargs[key] = getattr(args, key)
        kwargs['os_ironic_api_version'] = os_ironic_api_version
        client = iroclient.get_client(api_major_version, **kwargs)

        try:
            args.func(client, args)
        except exc.Unauthorized:
            raise exc.CommandError(_("Invalid OpenStack Identity credentials"))
        except exc.CommandError as e:
            subcommand_parser = self.subcommands[args.subparser_name]
            subcommand_parser.error(e)
Exemplo n.º 25
0
def check_empty_arg(arg, arg_descriptor):
    if not arg.strip():
        raise exc.CommandError(_('%(arg)s cannot be empty or only have blank'
                                 ' spaces') % {'arg': arg_descriptor})
Exemplo n.º 26
0
    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
        (api_major_version, os_ironic_api_version) = (
            self._check_version(options.ironic_api_version))

        subcommand_parser = self.get_subcommand_parser(api_major_version)
        self.parser = subcommand_parser

        # Handle top-level --help/-h before attempting to parse
        # a command off the command line
        if options.help or not argv:
            self.do_help(options)
            return 0

        # Parse args again and call whatever callback was selected
        args = subcommand_parser.parse_args(argv)

        # Short-circuit and deal with these commands 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()
            return 0

        if not (args.os_auth_token and (args.ironic_url or args.os_endpoint)):
            if not args.os_username:
                raise exc.CommandError(_("You must provide a username via "
                                         "either --os-username or via "
                                         "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(
                            'OpenStack Password: '******'t have a tty or the
            # user Ctl-D when prompted.
            if not args.os_password:
                raise exc.CommandError(_("You must provide a password via "
                                         "either --os-password, "
                                         "env[OS_PASSWORD], "
                                         "or prompted response"))

            if not (args.os_tenant_id or args.os_tenant_name or
                    args.os_project_id or args.os_project_name):
                raise exc.CommandError(
                    _("You must provide a project name or"
                      " project id via --os-project-name, --os-project-id,"
                      " env[OS_PROJECT_ID] or env[OS_PROJECT_NAME].  You may"
                      " use os-project and os-tenant interchangeably."))

            if not args.os_auth_url:
                raise exc.CommandError(_("You must provide an auth url via "
                                         "either --os-auth-url or via "
                                         "env[OS_AUTH_URL]"))

        endpoint = args.ironic_url or args.os_endpoint
        service_type = args.os_service_type or 'baremetal'
        project_id = args.os_project_id or args.os_tenant_id
        project_name = args.os_project_name or args.os_tenant_name

        if (args.os_auth_token and (args.ironic_url or args.os_endpoint)):
            kwargs = {
                'token': args.os_auth_token,
                'insecure': args.insecure,
                'timeout': args.timeout,
                'ca_file': args.os_cacert,
                'cert_file': args.os_cert,
                'key_file': args.os_key,
                'auth_ref': None,
            }
        elif (args.os_username and
              args.os_password and
              args.os_auth_url and
              (project_id or project_name)):

            keystone_session = kssession.Session.load_from_cli_options(args)

            kwargs = {
                'username': args.os_username,
                'user_domain_id': args.os_user_domain_id,
                'user_domain_name': args.os_user_domain_name,
                'password': args.os_password,
                'auth_token': args.os_auth_token,
                'project_id': project_id,
                'project_name': project_name,
                'project_domain_id': args.os_project_domain_id,
                'project_domain_name': args.os_project_domain_name,
            }
            keystone_auth = self._get_keystone_auth(keystone_session,
                                                    args.os_auth_url,
                                                    **kwargs)
            if not endpoint:
                svc_type = args.os_service_type
                region_name = args.os_region_name
                endpoint = keystone_auth.get_endpoint(keystone_session,
                                                      service_type=svc_type,
                                                      region_name=region_name)

            endpoint_type = args.os_endpoint_type or 'publicURL'
            kwargs = {
                'auth_url': args.os_auth_url,
                'session': keystone_session,
                'auth': keystone_auth,
                'service_type': service_type,
                'endpoint_type': endpoint_type,
                'region_name': args.os_region_name,
                'username': args.os_username,
                'password': args.os_password,
            }
        kwargs['os_ironic_api_version'] = os_ironic_api_version
        client = iroclient.Client(api_major_version, endpoint, **kwargs)

        try:
            args.func(client, args)
        except exc.Unauthorized:
            raise exc.CommandError(_("Invalid OpenStack Identity credentials"))