def get_template_contents(template_file=None, template_url=None,
                          files=None):

    # Transform a bare file path to a file:// URL.
    if template_file:  # nosec
        template_url = utils.normalise_file_path_to_url(template_file)
        tpl = request.urlopen(template_url).read()
    else:
        raise exceptions.CommandErrorException(_('Need to specify exactly '
                                                 'one of %(arg1)s, %(arg2)s '
                                                 'or %(arg3)s') %
                                               {'arg1': '--template-file',
                                                'arg2': '--template-url'})

    if not tpl:
        raise exceptions.CommandErrorException(_('Could not fetch '
                                                 'template from %s') %
                                               template_url)

    try:
        if isinstance(tpl, six.binary_type):
            tpl = tpl.decode('utf-8')
        template = template_format.parse(tpl)
    except ValueError as e:
        raise exceptions.CommandErrorException(_('Error parsing template '
                                                 '%(url)s %(error)s') %
                                               {'url': template_url,
                                                'error': e})
    return template
    def matches(self, min_version, max_version):
        """Matches the version object.

        Returns whether the version object represents a version
        greater than or equal to the minimum version and less than
        or equal to the maximum version.

        :param min_version: Minimum acceptable version.
        :param max_version: Maximum acceptable version.
        :returns: boolean

        If min_version is null then there is no minimum limit.
        If max_version is null then there is no maximum limit.
        If self is null then raise ValueError
        """

        if self.is_null():
            raise ValueError(_("Null APIVersion doesn't support 'matches'."))
        if max_version.is_null() and min_version.is_null():
            return True
        elif max_version.is_null():
            return min_version <= self
        elif min_version.is_null():
            return self <= max_version
        else:
            return min_version <= self <= max_version
    def __init__(self, version_str=None):
        """Create an API version object.

        :param version_str: String representation of APIVersionRequest.
                            Correct format is 'X.Y', where 'X' and 'Y'
                            are int values. None value should be used
                            to create Null APIVersionRequest, which is
                            equal to 0.0
        """
        self.ver_major = 0
        self.ver_minor = 0

        if version_str is not None:
            match = re.match(r"^([1-9]\d*)\.([1-9]\d*|0|latest)$", version_str)
            if match:
                self.ver_major = int(match.group(1))
                if match.group(2) == "latest":
                    # NOTE(andreykurilin): Infinity allows to easily determine
                    # latest version and doesn't require any additional checks
                    # in comparison methods.
                    self.ver_minor = float("inf")
                else:
                    self.ver_minor = int(match.group(2))
            else:
                msg = _("Invalid format of client version '%s'. "
                        "Expected format 'X.Y', where X is a major part and Y "
                        "is a minor part of version.") % version_str
                raise exceptions.UnsupportedVersion(msg)
示例#4
0
def format_args(args, parse_comma=True):
    '''Reformat a list of key-value arguments into a dict.

    Convert arguments into format expected by the API.
    '''
    if not args:
        return {}

    if parse_comma:
        # expect multiple invocations of --label (or other arguments) but fall
        # back to either , or ; delimited if only one --label is specified
        if len(args) == 1:
            args = args[0].replace(';', ',').split(',')

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

    return fmt_args
示例#5
0
 def take_action(self, parsed_args):
     client = _get_client(self, parsed_args)
     try:
         client.quotas.delete(parsed_args.project_id)
         print(_('Request to delete quotas has been accepted.'))
     except Exception as e:
         print("Delete for quotas failed: %(e)s" % {'e': e})
示例#6
0
class MethodNotAllowed(HTTPClientError):
    """HTTP 405 - Method Not Allowed.

    A request was made of a resource using a request method not supported
    by that resource.
    """
    http_status = 405
    message = _("Method Not Allowed")
示例#7
0
class Forbidden(HTTPClientError):
    """HTTP 403 - Forbidden.

    The request was a valid request, but the server is refusing to respond
    to it.
    """
    http_status = 403
    message = _("Forbidden")
示例#8
0
class NotFound(HTTPClientError):
    """HTTP 404 - Not Found.

    The requested resource could not be found but may be available again
    in the future.
    """
    http_status = 404
    message = _("Not Found")
示例#9
0
class Unauthorized(HTTPClientError):
    """HTTP 401 - Unauthorized.

    Similar to 403 Forbidden, but specifically for use when authentication
    is required and has failed or has not yet been provided.
    """
    http_status = 401
    message = _("Unauthorized")
示例#10
0
class MultipleChoices(HTTPRedirection):
    """HTTP 300 - Multiple Choices.

    Indicates multiple options for the resource that the client may follow.
    """

    http_status = 300
    message = _("Multiple Choices")
示例#11
0
    def _find_actions(self, subparsers, actions_module, version, do_help):
        msg = _(" (Supported by API versions '%(start)s' - '%(end)s')")
        for attr in (a for a in dir(actions_module) if a.startswith('do_')):
            # I prefer to be hyphen-separated instead of underscores.
            command = attr[3:].replace('_', '-')
            callback = getattr(actions_module, attr)
            desc = callback.__doc__ or ''
            if hasattr(callback, "versioned"):
                subs = api_versions.get_substitutions(callback)
                if do_help:
                    desc += msg % {'start': subs[0].start_version.get_string(),
                                   'end': subs[-1].end_version.get_string()}
                else:
                    for versioned_method in subs:
                        if version.matches(versioned_method.start_version,
                                           versioned_method.end_version):
                            callback = versioned_method.func
                            break
                    else:
                        continue

            action_help = desc.strip()
            arguments = getattr(callback, 'arguments', [])

            subparser = (
                subparsers.add_parser(command,
                                      help=action_help,
                                      description=desc,
                                      add_help=False,
                                      formatter_class=OpenStackHelpFormatter)
            )
            subparser.add_argument('-h', '--help',
                                   action='help',
                                   help=argparse.SUPPRESS,)
            self.subcommands[command] = subparser

            for (args, kwargs) in arguments:
                start_version = kwargs.get("start_version", None)
                if start_version:
                    start_version = api_versions.APIVersion(start_version)
                    end_version = kwargs.get("end_version", None)
                    if end_version:
                        end_version = api_versions.APIVersion(end_version)
                    else:
                        end_version = api_versions.APIVersion(
                            "%s.latest" % start_version.ver_major)
                    if do_help:
                        kwargs["help"] = kwargs.get("help", "") + (msg % {
                            "start": start_version.get_string(),
                            "end": end_version.get_string()})
                    else:
                        if not version.matches(start_version, end_version):
                            continue
                kw = kwargs.copy()
                kw.pop("start_version", None)
                kw.pop("end_version", None)
                subparser.add_argument(*args, **kwargs)
            subparser.set_defaults(func=callback)
示例#12
0
def discover_version(client, requested_version):
    server_start_version, server_end_version = _get_server_version_range(
        client)

    if (not requested_version.is_latest() and
            requested_version != APIVersion('1.1')):
        if server_start_version.is_null() and server_end_version.is_null():
            raise exceptions.UnsupportedVersion(
                _("Server doesn't support microversions"))
        if not requested_version.matches(server_start_version,
                                         server_end_version):
            raise exceptions.UnsupportedVersion(
                _("The specified version isn't supported by server. The valid "
                  "version range is '%(min)s' to '%(max)s'") % {
                    "min": server_start_version.get_string(),
                    "max": server_end_version.get_string()})
        return requested_version

    min_version = APIVersion(MIN_API_VERSION)
    max_version = APIVersion(MAX_API_VERSION)
    if server_start_version.is_null() and server_end_version.is_null():
        return APIVersion("1.1")
    elif min_version > server_end_version:
        raise exceptions.UnsupportedVersion(
            _("Server version is too old. The client valid version range is "
              "'%(client_min)s' to '%(client_max)s'. The server valid version "
              "range is '%(server_min)s' to '%(server_max)s'.") % {
                  'client_min': min_version.get_string(),
                  'client_max': max_version.get_string(),
                  'server_min': server_start_version.get_string(),
                  'server_max': server_end_version.get_string()})
    elif max_version < server_start_version:
        raise exceptions.UnsupportedVersion(
            _("Server version is too new. The client valid version range is "
              "'%(client_min)s' to '%(client_max)s'. The server valid version "
              "range is '%(server_min)s' to '%(server_max)s'.") % {
                  'client_min': min_version.get_string(),
                  'client_max': max_version.get_string(),
                  'server_min': server_start_version.get_string(),
                  'server_max': server_end_version.get_string()})
    elif max_version <= server_end_version:
        return max_version
    elif server_end_version < max_version:
        return server_end_version
示例#13
0
def discover_version(client, requested_version):
    server_start_version, server_end_version = _get_server_version_range(
        client)

    if (not requested_version.is_latest() and
            requested_version != APIVersion('1.1')):
        if server_start_version.is_null() and server_end_version.is_null():
            raise exceptions.UnsupportedVersion(
                _("Server doesn't support microversions"))
        if not requested_version.matches(server_start_version,
                                         server_end_version):
            raise exceptions.UnsupportedVersion(
                _("The specified version isn't supported by server. The valid "
                  "version range is '%(min)s' to '%(max)s'") % {
                    "min": server_start_version.get_string(),
                    "max": server_end_version.get_string()})
        return requested_version

    min_version = APIVersion(MIN_API_VERSION)
    max_version = APIVersion(MAX_API_VERSION)
    if server_start_version.is_null() and server_end_version.is_null():
        return APIVersion("1.1")
    elif min_version > server_end_version:
        raise exceptions.UnsupportedVersion(
            _("Server version is too old. The client valid version range is "
              "'%(client_min)s' to '%(client_max)s'. The server valid version "
              "range is '%(server_min)s' to '%(server_max)s'.") % {
                  'client_min': min_version.get_string(),
                  'client_max': max_version.get_string(),
                  'server_min': server_start_version.get_string(),
                  'server_max': server_end_version.get_string()})
    elif max_version < server_start_version:
        raise exceptions.UnsupportedVersion(
            _("Server version is too new. The client valid version range is "
              "'%(client_min)s' to '%(client_max)s'. The server valid version "
              "range is '%(server_min)s' to '%(server_max)s'.") % {
                  'client_min': min_version.get_string(),
                  'client_max': max_version.get_string(),
                  'server_min': server_start_version.get_string(),
                  'server_max': server_end_version.get_string()})
    elif max_version <= server_end_version:
        return max_version
    elif server_end_version < max_version:
        return server_end_version
示例#14
0
def _get_client_class_and_version(version):
    if not isinstance(version, api_versions.APIVersion):
        version = api_versions.get_api_version(version)
    else:
        api_versions.check_major_version(version)
    if version.is_latest():
        raise exceptions.UnsupportedVersion(
            _('The version should be explicit, not latest.'))
    return version, importutils.import_class('zunclient.v%s.client.Client' %
                                             version.ver_major)
示例#15
0
def check_major_version(api_version):
    """Checks major part of ``APIVersion`` obj is supported.

    :raises exceptions.UnsupportedVersion: if major part is not supported
    """
    available_versions = get_available_major_versions()
    if (not api_version.is_null() and
            str(api_version.ver_major) not in available_versions):
        if len(available_versions) == 1:
            msg = _("Invalid client version '%(version)s'. "
                    "Major part should be '%(major)s'") % {
                "version": api_version.get_string(),
                "major": available_versions[0]}
        else:
            msg = _("Invalid client version '%(version)s'. "
                    "Major part must be one of: '%(major)s'") % {
                "version": api_version.get_string(),
                "major": ", ".join(available_versions)}
        raise exceptions.UnsupportedVersion(msg)
示例#16
0
def check_major_version(api_version):
    """Checks major part of ``APIVersion`` obj is supported.

    :raises exceptions.UnsupportedVersion: if major part is not supported
    """
    available_versions = get_available_major_versions()
    if (not api_version.is_null() and
            str(api_version.ver_major) not in available_versions):
        if len(available_versions) == 1:
            msg = _("Invalid client version '%(version)s'. "
                    "Major part should be '%(major)s'") % {
                "version": api_version.get_string(),
                "major": available_versions[0]}
        else:
            msg = _("Invalid client version '%(version)s'. "
                    "Major part must be one of: '%(major)s'") % {
                "version": api_version.get_string(),
                "major": ", ".join(available_versions)}
        raise exceptions.UnsupportedVersion(msg)
示例#17
0
 def take_action(self, parsed_args):
     client = _get_client(self, parsed_args)
     opts = {}
     opts['image_id'] = parsed_args.uuid
     try:
         client.images.delete(**opts)
         print(_('Request to delete image %s has been accepted.')
               % opts['image_id'])
     except Exception as e:
         print("Delete for image %(image)s failed: %(e)s" %
               {'image': opts['image_id'], 'e': e})
示例#18
0
    def get_string(self):
        """Version string representation.

        Converts object to string representation which if used to create
        an APIVersion object results in the same version.
        """
        if self.is_null():
            raise ValueError(
                _("Null APIVersion cannot be converted to string."))
        elif self.is_latest():
            return "%s.%s" % (self.ver_major, "latest")
        return "%s.%s" % (self.ver_major, self.ver_minor)
示例#19
0
    def get_string(self):
        """Version string representation.

        Converts object to string representation which if used to create
        an APIVersion object results in the same version.
        """
        if self.is_null():
            raise ValueError(
                _("Null APIVersion cannot be converted to string."))
        elif self.is_latest():
            return "%s.%s" % (self.ver_major, "latest")
        return "%s.%s" % (self.ver_major, self.ver_minor)
示例#20
0
def print_list(objs,
               fields,
               formatters=None,
               sortby_index=0,
               mixed_case_fields=None,
               field_labels=None):
    """Print a list or objects as a table, one row per object.

    :param objs: iterable of :class:`Resource`
    :param fields: attributes that correspond to columns, in order
    :param formatters: `dict` of callables for field formatting
    :param sortby_index: index of the field for sorting table rows
    :param mixed_case_fields: fields corresponding to object attributes that
        have mixed case names (e.g., 'serverId')
    :param field_labels: Labels to use in the heading of the table, default to
        fields.
    """
    formatters = formatters or {}
    mixed_case_fields = mixed_case_fields or []
    field_labels = field_labels or fields
    if len(field_labels) != len(fields):
        raise ValueError(
            _("Field labels list %(labels)s has different number "
              "of elements than fields list %(fields)s"), {
                  'labels': field_labels,
                  'fields': fields
              })

    if sortby_index is None:
        kwargs = {}
    else:
        kwargs = {'sortby': field_labels[sortby_index]}
    pt = prettytable.PrettyTable(field_labels)
    pt.align = 'l'

    for o in objs:
        row = []
        for field in fields:
            if field in formatters:
                row.append(formatters[field](o))
            else:
                if field in mixed_case_fields:
                    field_name = field.replace(' ', '_')
                else:
                    field_name = field.lower().replace(' ', '_')
                data = getattr(o, field_name, '')
                row.append(data)
        pt.add_row(row)

    if six.PY3:
        print(encodeutils.safe_encode(pt.get_string(**kwargs)).decode())
    else:
        print(encodeutils.safe_encode(pt.get_string(**kwargs)))
 def take_action(self, parsed_args):
     client = _get_client(self, parsed_args)
     containers = parsed_args.container
     for container in containers:
         try:
             client.containers.unpause(container)
             print(
                 _('Request to unpause container %s has been accepted') %
                 container)
         except Exception as e:
             print("unpause for container %(container)s failed: %(e)s" % {
                 'container': container,
                 'e': e
             })
 def take_action(self, parsed_args):
     client = _get_client(self, parsed_args)
     container = parsed_args.container
     name = parsed_args.name
     try:
         client.containers.rename(container, name)
         print(
             _('Request to rename container %s has been accepted') %
             container)
     except Exception as e:
         print("rename for container %(container)s failed: %(e)s" % {
             'container': container,
             'e': e
         })
 def take_action(self, parsed_args):
     client = _get_client(self, parsed_args)
     containers = parsed_args.container
     for container in containers:
         try:
             client.containers.stop(container, parsed_args.timeout)
             print(
                 _('Request to stop container %s has been accepted.') %
                 container)
         except Exception as e:
             print("Stop for container %(container)s failed: %(e)s" % {
                 'container': container,
                 'e': e
             })
示例#24
0
 def take_action(self, parsed_args):
     client = _get_client(self, parsed_args)
     registries = parsed_args.registry
     for registry in registries:
         opts = {}
         opts['id'] = registry
         opts = zun_utils.remove_null_parms(**opts)
         try:
             client.registries.delete(**opts)
             print(_('Request to delete registry %s has been accepted.')
                   % registry)
         except Exception as e:
             print("Delete for registry %(registry)s failed: %(e)s" %
                   {'registry': registry, 'e': e})
示例#25
0
class RequestEntityTooLarge(HTTPClientError):
    """HTTP 413 - Request Entity Too Large.

    The request is larger than the server is willing or able to process.
    """
    http_status = 413
    message = _("Request Entity Too Large")

    def __init__(self, *args, **kwargs):
        try:
            self.retry_after = int(kwargs.pop('retry_after'))
        except (KeyError, ValueError):
            self.retry_after = 0

        super(RequestEntityTooLarge, self).__init__(*args, **kwargs)
示例#26
0
 def take_action(self, parsed_args):
     client = _get_client(self, parsed_args)
     containers = parsed_args.container
     force = getattr(parsed_args, 'force')
     for container in containers:
         try:
             client.containers.delete(container, force)
             print(
                 _('Request to delete container %s has been accepted.') %
                 container)
         except Exception as e:
             print("Delete for container %(container)s failed: %(e)s" % {
                 'container': container,
                 'e': e
             })
示例#27
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
示例#28
0
 def take_action(self, parsed_args):
     client = _get_client(self, parsed_args)
     capsules = parsed_args.capsule
     for capsule in capsules:
         opts = {}
         opts['id'] = capsule
         try:
             client.capsules.delete(**opts)
             print(
                 _('Request to delete capsule %s has been accepted.') %
                 capsule)
         except Exception as e:
             print("Delete for capsule %(capsule)s failed: %(e)s" % {
                 'capsule': capsule,
                 'e': e
             })
示例#29
0
 def take_action(self, parsed_args):
     client = _get_client(self, parsed_args)
     container = parsed_args.container
     opts = {}
     opts['id'] = parsed_args.container
     opts['signal'] = parsed_args.signal
     try:
         client.containers.kill(**opts)
         print(
             _('Request to send kill signal to container %s has '
               'been accepted') % container)
     except Exception as e:
         print("kill signal for container %(container)s failed: %(e)s" % {
             'container': container,
             'e': e
         })
示例#30
0
    def _find_actions(self, subparsers, actions_module, version, do_help):
        msg = _(" (Supported by API versions '%(start)s' - '%(end)s')")
        for attr in (a for a in dir(actions_module) if a.startswith('do_')):
            # I prefer to be hyphen-separated instead of underscores.
            command = attr[3:].replace('_', '-')
            callback = getattr(actions_module, attr)
            desc = callback.__doc__ or ''
            if hasattr(callback, "versioned"):
                subs = api_versions.get_substitutions(callback)
                if do_help:
                    desc += msg % {
                        'start': subs[0].start_version.get_string(),
                        'end': subs[-1].end_version.get_string()
                    }
                else:
                    for versioned_method in subs:
                        if version.matches(versioned_method.start_version,
                                           versioned_method.end_version):
                            callback = versioned_method.func
                            break
                    else:
                        continue

            action_help = desc.strip()
            exclusive_args = getattr(callback, 'exclusive_args', {})
            arguments = getattr(callback, 'arguments', [])

            subparser = (subparsers.add_parser(
                command,
                help=action_help,
                description=desc,
                add_help=False,
                formatter_class=OpenStackHelpFormatter))
            subparser.add_argument(
                '-h',
                '--help',
                action='help',
                help=argparse.SUPPRESS,
            )
            self.subcommands[command] = subparser

            self._add_subparser_args(subparser, arguments, version, do_help,
                                     msg)
            self._add_subparser_exclusive_args(subparser, exclusive_args,
                                               version, do_help, msg)
            subparser.set_defaults(func=callback)
示例#31
0
def print_list(objs, fields, formatters=None, sortby_index=0,
               mixed_case_fields=None, field_labels=None):
    """Print a list or objects as a table, one row per object.

    :param objs: iterable of :class:`Resource`
    :param fields: attributes that correspond to columns, in order
    :param formatters: `dict` of callables for field formatting
    :param sortby_index: index of the field for sorting table rows
    :param mixed_case_fields: fields corresponding to object attributes that
        have mixed case names (e.g., 'serverId')
    :param field_labels: Labels to use in the heading of the table, default to
        fields.
    """
    formatters = formatters or {}
    mixed_case_fields = mixed_case_fields or []
    field_labels = field_labels or fields
    if len(field_labels) != len(fields):
        raise ValueError(_("Field labels list %(labels)s has different number "
                           "of elements than fields list %(fields)s"),
                         {'labels': field_labels, 'fields': fields})

    if sortby_index is None:
        kwargs = {}
    else:
        kwargs = {'sortby': field_labels[sortby_index]}
    pt = prettytable.PrettyTable(field_labels)
    pt.align = 'l'

    for o in objs:
        row = []
        for field in fields:
            if field in formatters:
                row.append(formatters[field](o))
            else:
                if field in mixed_case_fields:
                    field_name = field.replace(' ', '_')
                else:
                    field_name = field.lower().replace(' ', '_')
                data = getattr(o, field_name, '')
                row.append(data)
        pt.add_row(row)

    if six.PY3:
        print(encodeutils.safe_encode(pt.get_string(**kwargs)).decode())
    else:
        print(encodeutils.safe_encode(pt.get_string(**kwargs)))
示例#32
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 = jsonutils.loads(value)
    except ValueError:
        pass

    return (key, value)
示例#33
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)
示例#34
0
    def find(self, **kwargs):
        """Find a single item with attributes matching ``**kwargs``.

        This isn't very efficient: it loads the entire list then filters on
        the Python side.
        """
        matches = self.findall(**kwargs)
        num_matches = len(matches)
        if num_matches == 0:
            msg = _("No %(name)s matching %(args)s.") % {
                'name': self.resource_class.__name__,
                'args': kwargs
            }
            raise exceptions.NotFound(msg)
        elif num_matches > 1:
            raise exceptions.NoUniqueMatch()
        else:
            return matches[0]
 def take_action(self, parsed_args):
     client = _get_client(self, parsed_args)
     for container in parsed_args.containers:
         opts = {}
         opts['id'] = container
         if parsed_args.image:
             opts['image'] = parsed_args.image
         if parsed_args.image_driver:
             opts['image_driver'] = parsed_args.image_driver
         try:
             client.containers.rebuild(**opts)
             print(
                 _('Request to rebuild container %s has '
                   'been accepted') % container)
         except Exception as e:
             print("rebuild container %(container)s failed: %(e)s" % {
                 'container': container,
                 'e': e
             })
 def take_action(self, parsed_args):
     client = _get_client(self, parsed_args)
     containers = parsed_args.container
     for container in containers:
         opts = {}
         opts['id'] = container
         opts['force'] = parsed_args.force
         opts['all_tenants'] = parsed_args.all_tenants
         opts = zun_utils.remove_null_parms(**opts)
         try:
             client.containers.delete(**opts)
             print(
                 _('Request to delete container %s has been accepted.') %
                 container)
         except Exception as e:
             print("Delete for container %(container)s failed: %(e)s" % {
                 'container': container,
                 'e': e
             })
示例#37
0
    def _find_actions(self, subparsers, actions_module, version, do_help):
        msg = _(" (Supported by API versions '%(start)s' - '%(end)s')")
        for attr in (a for a in dir(actions_module) if a.startswith('do_')):
            # I prefer to be hyphen-separated instead of underscores.
            command = attr[3:].replace('_', '-')
            callback = getattr(actions_module, attr)
            desc = callback.__doc__ or ''
            if hasattr(callback, "versioned"):
                subs = api_versions.get_substitutions(callback)
                if do_help:
                    desc += msg % {'start': subs[0].start_version.get_string(),
                                   'end': subs[-1].end_version.get_string()}
                else:
                    for versioned_method in subs:
                        if version.matches(versioned_method.start_version,
                                           versioned_method.end_version):
                            callback = versioned_method.func
                            break
                    else:
                        continue

            action_help = desc.strip()
            exclusive_args = getattr(callback, 'exclusive_args', {})
            arguments = getattr(callback, 'arguments', [])

            subparser = (
                subparsers.add_parser(command,
                                      help=action_help,
                                      description=desc,
                                      add_help=False,
                                      formatter_class=OpenStackHelpFormatter)
            )
            subparser.add_argument('-h', '--help',
                                   action='help',
                                   help=argparse.SUPPRESS,)
            self.subcommands[command] = subparser

            self._add_subparser_args(subparser, arguments, version, do_help,
                                     msg)
            self._add_subparser_exclusive_args(subparser, exclusive_args,
                                               version, do_help, msg)
            subparser.set_defaults(func=callback)
示例#38
0
def print_dict(dct, dict_property="Property", wrap=0, value_fields=None):
    """Print a `dict` as a table of two columns.

    :param dct: `dict` to print
    :param dict_property: name of the first column
    :param wrap: wrapping for the second column
    :param value_fields: attributes that correspond to columns, in order
    """
    pt = prettytable.PrettyTable([dict_property, 'Value'])
    if value_fields:
        pt = prettytable.PrettyTable([dict_property] + list(value_fields))
    pt.align = 'l'
    for k, v in dct.items():
        # convert dict to str to check length
        if isinstance(v, dict) and not value_fields:
            v = six.text_type(keys_and_vals_to_strs(v))
        if wrap > 0:
            v = textwrap.fill(six.text_type(v), wrap)
        elif wrap < 0:
            raise ValueError(_("Wrap argument should be a positive integer"))
        # if value has a newline, add in multiple rows
        # e.g. fault with stacktrace
        if v and isinstance(v, six.string_types) and r'\n' in v:
            lines = v.strip().split(r'\n')
            col1 = k
            for line in lines:
                pt.add_row([col1, line])
                col1 = ''
        elif isinstance(v, dict):
            vals = [v[field] for field in v if field in value_fields]
            pt.add_row([k] + vals)
        elif isinstance(v, list):
            val = str([str(i) for i in v])
            pt.add_row([k, val])
        else:
            pt.add_row([k, v])

    if six.PY3:
        print(encodeutils.safe_encode(pt.get_string()).decode())
    else:
        print(encodeutils.safe_encode(pt.get_string()))
示例#39
0
def print_dict(dct, dict_property="Property", wrap=0, value_fields=None):
    """Print a `dict` as a table of two columns.

    :param dct: `dict` to print
    :param dict_property: name of the first column
    :param wrap: wrapping for the second column
    :param value_fields: attributes that correspond to columns, in order
    """
    pt = prettytable.PrettyTable([dict_property, 'Value'])
    if value_fields:
        pt = prettytable.PrettyTable([dict_property] + list(value_fields))
    pt.align = 'l'
    for k, v in dct.items():
        # convert dict to str to check length
        if isinstance(v, dict) and not value_fields:
            v = six.text_type(keys_and_vals_to_strs(v))
        if wrap > 0:
            v = textwrap.fill(six.text_type(v), wrap)
        elif wrap < 0:
            raise ValueError(_("Wrap argument should be a positive integer"))
        # if value has a newline, add in multiple rows
        # e.g. fault with stacktrace
        if v and isinstance(v, six.string_types) and r'\n' in v:
            lines = v.strip().split(r'\n')
            col1 = k
            for line in lines:
                pt.add_row([col1, line])
                col1 = ''
        elif isinstance(v, dict):
            vals = [v[field] for field in v if field in value_fields]
            pt.add_row([k] + vals)
        elif isinstance(v, list):
            val = str([str(i) for i in v])
            pt.add_row([k, val])
        else:
            pt.add_row([k, v])

    if six.PY3:
        print(encodeutils.safe_encode(pt.get_string()).decode())
    else:
        print(encodeutils.safe_encode(pt.get_string()))
示例#40
0
class HttpError(ClientException):
    """The base exception class for all HTTP exceptions."""
    http_status = 0
    message = _("HTTP Error")

    def __init__(self,
                 message=None,
                 details=None,
                 response=None,
                 request_id=None,
                 url=None,
                 method=None,
                 http_status=None):
        self.http_status = http_status or self.http_status
        self.message = message or self.message
        self.details = details
        self.request_id = request_id
        self.response = response
        self.url = url
        self.method = method
        formatted_string = "%s (HTTP %s)" % (self.message, self.http_status)
        if request_id:
            formatted_string += " (Request-ID: %s)" % request_id
        super(HttpError, self).__init__(formatted_string)
示例#41
0
    def find(self, base_url=None, **kwargs):
        """Find a single item with attributes matching ``**kwargs``.

        :param base_url: if provided, the generated URL will be appended to it
        """
        kwargs = self._filter_kwargs(kwargs)

        rl = self._list(
            '%(base_url)s%(query)s' % {
                'base_url': self.build_url(base_url=base_url, **kwargs),
                'query': '?%s' % parse.urlencode(kwargs) if kwargs else '',
            }, self.collection_key)
        num = len(rl)

        if num == 0:
            msg = _("No %(name)s matching %(args)s.") % {
                'name': self.resource_class.__name__,
                'args': kwargs
            }
            raise exceptions.NotFound(msg)
        elif num > 1:
            raise exceptions.NoUniqueMatch
        else:
            return rl[0]
示例#42
0
def decode_file_data(data):
    # Py3 raises binascii.Error instead of TypeError as in Py27
    try:
        return base64.b64decode(data)
    except (TypeError, binascii.Error):
        raise exc.CommandError(_('Invalid Base 64 file data.'))
示例#43
0
def decode_file_data(data):
    # Py3 raises binascii.Error instead of TypeError as in Py27
    try:
        return base64.b64decode(data)
    except (TypeError, binascii.Error):
        raise exc.CommandError(_('Invalid Base 64 file data.'))
from oslo_serialization import jsonutils

from zunclient.common import cliutils as utils
from zunclient.common import template_utils
from zunclient.common import utils as zun_utils
from zunclient.i18n import _


def _show_capsule(capsule):
    zun_utils.format_container_addresses(capsule)
    utils.print_dict(capsule._info)


@utils.arg('-f', '--template-file', metavar='<file>',
           required=True, help=_('Path to the template.'))
def do_capsule_create(cs, args):
    """Create a capsule."""
    opts = {}
    if args.template_file:
        template = template_utils.get_template_contents(
            args.template_file)
        opts['template'] = template
        cs.capsules.create(**opts)
        print("Request to create capsule has been accepted.")


@utils.arg('--all-projects',
           action="store_true",
           default=False,
           help='List containers in all projects')
示例#45
0
LOG = logging.getLogger(__name__)
if not LOG.handlers:
    LOG.addHandler(logging.StreamHandler())


HEADER_NAME = "OpenStack-API-Version"
SERVICE_TYPE = "container"
MIN_API_VERSION = '1.1'
MAX_API_VERSION = '1.32'
DEFAULT_API_VERSION = '1.latest'

_SUBSTITUTIONS = {}


_type_error_msg = _("'%(other)s' should be an instance of '%(cls)s'")


class APIVersion(object):
    """This class represents an API Version Request.

    This class provides convenience methods for manipulation
    and comparison of version numbers that we need to do to
    implement microversions.
    """

    def __init__(self, version_str=None):
        """Create an API version object.

        :param version_str: String representation of APIVersionRequest.
                            Correct format is 'X.Y', where 'X' and 'Y'
示例#46
0
    def main(self, argv):

        # NOTE(Christoph Jansen): With Python 3.4 argv somehow becomes a Map.
        #                         This hack fixes it.
        argv = list(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)

        api_version = api_versions.get_api_version(options.zun_api_version)

        # 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'

        do_help = "help" in args
        subcommand_parser = self.get_subcommand_parser(
            api_version, do_help=do_help)

        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_project_name, os_project_id,
         os_user_domain_id, os_user_domain_name,
         os_project_domain_id, os_project_domain_name,
         os_auth_url, os_auth_system, endpoint_type,
         service_type, bypass_url, insecure, os_cacert, os_cert, os_key) = (
            (args.os_username, args.os_project_name, args.os_project_id,
             args.os_user_domain_id, args.os_user_domain_name,
             args.os_project_domain_id, args.os_project_domain_name,
             args.os_auth_url, args.os_auth_system, args.endpoint_type,
             args.service_type, args.bypass_url, args.insecure,
             args.os_cacert, args.os_cert, args.os_key)
        )

        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_project_name and not os_project_id:
                raise exc.CommandError("You must provide a project name "
                                       "or project id via --os-project-name, "
                                       "--os-project-id, env[OS_PROJECT_NAME] "
                                       "or env[OS_PROJECT_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 Zun 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')

        client = base_client

        if not do_help:
            if api_version.is_latest():
                # This client is just used to discover api version.
                # Version API needn't microversion, so we just pass
                # version 1.1 at here.
                self.cs = client.Client(
                    version=api_versions.APIVersion("1.1"),
                    username=os_username,
                    password=os_password,
                    project_id=os_project_id,
                    project_name=os_project_name,
                    user_domain_id=os_user_domain_id,
                    user_domain_name=os_user_domain_name,
                    project_domain_id=os_project_domain_id,
                    project_domain_name=os_project_domain_name,
                    auth_url=os_auth_url,
                    service_type=service_type,
                    region_name=args.os_region_name,
                    endpoint_override=bypass_url,
                    interface=endpoint_type,
                    insecure=insecure,
                    cacert=os_cacert)
                api_version = api_versions.discover_version(self.cs,
                                                            api_version)

            min_version = api_versions.APIVersion(api_versions.MIN_API_VERSION)
            max_version = api_versions.APIVersion(api_versions.MAX_API_VERSION)
            if not api_version.matches(min_version, max_version):
                raise exc.CommandError(
                    _("The specified version isn't supported by "
                      "client. The valid version range is '%(min)s' "
                      "to '%(max)s'") % {
                        "min": min_version.get_string(),
                        "max": max_version.get_string()}
                )

        kwargs = {}
        if profiler:
            kwargs["profile"] = args.profile

        self.cs = client.Client(version=api_version,
                                username=os_username,
                                password=os_password,
                                project_id=os_project_id,
                                project_name=os_project_name,
                                user_domain_id=os_user_domain_id,
                                user_domain_name=os_user_domain_name,
                                project_domain_id=os_project_domain_id,
                                project_domain_name=os_project_domain_name,
                                auth_url=os_auth_url,
                                service_type=service_type,
                                region_name=args.os_region_name,
                                endpoint_override=bypass_url,
                                interface=endpoint_type,
                                insecure=insecure,
                                cacert=os_cacert,
                                cert=os_cert,
                                key=os_key,
                                **kwargs)

        args.func(self.cs, args)

        if profiler and args.profile:
            trace_id = profiler.get().get_base_id()
            print("To display trace use the command:\n\n"
                  "  osprofiler trace show --html %s " % trace_id)
示例#47
0
 def __init__(self, missing):
     self.missing = missing
     msg = _("Missing arguments: %s") % ", ".join(missing)
     super(MissingArgs, self).__init__(msg)
示例#48
0
 def __init__(self, endpoints=None):
     super(AmbiguousEndpoints, self).__init__(
         _("AmbiguousEndpoints: %r") % endpoints)
     self.endpoints = endpoints
示例#49
0
 def __init__(self, opt_names):
     super(AuthPluginOptionsMissing, self).__init__(
         _("Authentication failed. Missing options: %s") %
         ", ".join(opt_names))
     self.opt_names = opt_names
示例#50
0
 def __init__(self, auth_system):
     super(AuthSystemNotFound, self).__init__(
         _("AuthSystemNotFound: %r") % auth_system)
     self.auth_system = auth_system