Example #1
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(404, msg)
        elif num > 1:
            raise exceptions.NoUniqueMatch
        else:
            return rl[0]
Example #2
0
def bool_from_string(subject, strict=False, default=False):
    """Interpret a string as a boolean.

    A case-insensitive match is performed such that strings matching 't',
    'true', 'on', 'y', 'yes', or '1' are considered True and, when
    `strict=False`, anything else returns the value specified by 'default'.

    Useful for JSON-decoded stuff and config file parsing.

    If `strict=True`, unrecognized values, including None, will raise a
    ValueError which is useful when parsing values passed in from an API call.
    Strings yielding False are 'f', 'false', 'off', 'n', 'no', or '0'.
    """
    if not isinstance(subject, six.string_types):
        subject = six.text_type(subject)

    lowered = subject.strip().lower()

    if lowered in TRUE_STRINGS:
        return True
    elif lowered in FALSE_STRINGS:
        return False
    elif strict:
        acceptable = ', '.join(
            "'%s'" % s for s in sorted(TRUE_STRINGS + FALSE_STRINGS))
        msg = _("Unrecognized value '%(val)s', acceptable values are:"
                " %(acceptable)s") % {'val': subject,
                                      'acceptable': acceptable}
        raise ValueError(msg)
    else:
        return default
Example #3
0
def string_to_bytes(text, unit_system='IEC', return_int=False):
    """Converts a string into an float representation of bytes.

    The units supported for IEC ::

        Kb(it), Kib(it), Mb(it), Mib(it), Gb(it), Gib(it), Tb(it), Tib(it)
        KB, KiB, MB, MiB, GB, GiB, TB, TiB

    The units supported for SI ::

        kb(it), Mb(it), Gb(it), Tb(it)
        kB, MB, GB, TB

    Note that the SI unit system does not support capital letter 'K'

    :param text: String input for bytes size conversion.
    :param unit_system: Unit system for byte size conversion.
    :param return_int: If True, returns integer representation of text
                       in bytes. (default: decimal)
    :returns: Numerical representation of text in bytes.
    :raises ValueError: If text has an invalid value.

    """
    try:
        base, reg_ex = UNIT_SYSTEM_INFO[unit_system]
    except KeyError:
        msg = _('Invalid unit system: "%s"') % unit_system
        raise ValueError(msg)
    match = reg_ex.match(text)
    if match:
        magnitude = float(match.group(1))
        unit_prefix = match.group(2)
        if match.group(3) in ['b', 'bit']:
            magnitude /= 8
    else:
        msg = _('Invalid string format: %s') % text
        raise ValueError(msg)
    if not unit_prefix:
        res = magnitude
    else:
        res = magnitude * pow(base, UNIT_PREFIX_EXPONENT[unit_prefix])
    if return_int:
        return int(math.ceil(res))
    return res
Example #4
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 get_class(api_name, version, version_map):
        """Returns the client class for the requested API version

        :param api_name: the name of the API, e.g. 'compute', 'image', etc
        :param version: the requested API version
        :param version_map: a dict of client classes keyed by version
        :rtype: a client class for the requested API version
        """
        try:
            client_path = version_map[str(version)]
        except (KeyError, ValueError):
            msg = _("Invalid %(api_name)s client version '%(version)s'. "
                    "Must be one of: %(version_map)s") % {
                        'api_name': api_name,
                        'version': version,
                        'version_map': ', '.join(version_map.keys())
                    }
            raise exceptions.UnsupportedVersion(msg)

        return importutils.import_class(client_path)
 def __init__(self, auth_system):
     super(AuthSystemNotFound, self).__init__(
         _("AuthSystemNotFound: %s") % repr(auth_system))
     self.auth_system = auth_system
 def __init__(self, opt_names):
     super(AuthPluginOptionsMissing, self).__init__(
         _("Authentication failed. Missing options: %s") %
         ", ".join(opt_names))
     self.opt_names = opt_names
 def __init__(self, missing):
     self.missing = missing
     msg = _("Missing arguments: %s") % ", ".join(missing)
     super(MissingArgs, self).__init__(msg)
 def __init__(self, endpoints=None):
     super(AmbiguousEndpoints, self).__init__(
         _("AmbiguousEndpoints: %s") % repr(endpoints))
     self.endpoints = endpoints
Example #10
0
    def client_request(self, client, method, url, **kwargs):
        """Send an http request using `client`'s endpoint and specified `url`.

        If request was rejected as unauthorized (possibly because the token is
        expired), issue one authorization attempt and send the request once
        again.

        :param client: instance of BaseClient descendant
        :param method: method of HTTP request
        :param url: URL of HTTP request
        :param kwargs: any other parameter that can be passed to
            `HTTPClient.request`
        """

        filter_args = {
            "endpoint_type": client.endpoint_type or self.endpoint_type,
            "service_type": client.service_type,
        }
        token, endpoint = (self.cached_token, client.cached_endpoint)
        just_authenticated = False
        if not (token and endpoint):
            try:
                token, endpoint = self.auth_plugin.token_and_endpoint(
                    **filter_args)
            except exceptions.EndpointException:
                pass
            if not (token and endpoint):
                self.authenticate()
                just_authenticated = True
                token, endpoint = self.auth_plugin.token_and_endpoint(
                    **filter_args)
                if not (token and endpoint):
                    raise exceptions.AuthorizationFailure(
                        _("Cannot find endpoint or token for request"))

        old_token_endpoint = (token, endpoint)
        kwargs.setdefault("headers", {})["X-Auth-Token"] = token
        self.cached_token = token
        client.cached_endpoint = endpoint
        # Perform the request once. If we get Unauthorized, then it
        # might be because the auth token expired, so try to
        # re-authenticate and try again. If it still fails, bail.
        try:
            return self.request(
                method, self.concat_url(endpoint, url), **kwargs)
        except exceptions.Unauthorized as unauth_ex:
            if just_authenticated:
                raise
            self.cached_token = None
            client.cached_endpoint = None
            self.authenticate()
            try:
                token, endpoint = self.auth_plugin.token_and_endpoint(
                    **filter_args)
            except exceptions.EndpointException:
                raise unauth_ex
            if (not (token and endpoint) or
                    old_token_endpoint == (token, endpoint)):
                raise unauth_ex
            self.cached_token = token
            client.cached_endpoint = endpoint
            kwargs["headers"]["X-Auth-Token"] = token
            return self.request(
                method, self.concat_url(endpoint, url), **kwargs)
Example #11
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:

        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 = strutils.safe_encode(name_or_id)
        else:
            tmp_id = strutils.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)