Example #1
0
    def get_endpoint(self, session, interface=None, version=None, **kwargs):
        """Return an endpoint for the client.

        There are no required keyword arguments to ``get_endpoint`` as a plugin
        implementation should use best effort with the information available to
        determine the endpoint.

        :param session: The session object that the auth_plugin belongs to.
        :type session: keystoneauth1.session.Session
        :param version: The version number required for this endpoint.
        :type version: tuple or str
        :param str interface: what visibility the endpoint should have.

        :returns: The base URL that will be used to talk to the required
                  service or None if not available.
        :rtype: string
        """
        if interface == plugin.AUTH_INTERFACE:
            return self._identity_uri

        if not version:
            # NOTE(jamielennox): This plugin can only be used within auth_token
            # and auth_token will always provide version= with requests.
            return None

        if not self._discover:
            self._discover = discover.Discover(session,
                                               url=self._identity_uri,
                                               authenticated=False)

        if not self._discover.url_for(version):
            # NOTE(jamielennox): The requested version is not supported by the
            # identity server.
            return None

        # NOTE(jamielennox): for backwards compatibility here we don't
        # actually use the URL from discovery we hack it up instead. :(
        # NOTE(blk-u): Normalizing the version is a workaround for bug 1450272.
        # This can be removed once that's fixed. Also fix the docstring for the
        # version parameter to be just "tuple".
        version = discover.normalize_version_number(version)
        if discover.version_match((2, 0), version):
            return '%s/v2.0' % self._identity_uri
        elif discover.version_match((3, 0), version):
            return '%s/v3' % self._identity_uri

        # NOTE(jamielennox): This plugin will only get called from auth_token
        # middleware. The middleware should never request a version that the
        # plugin doesn't know how to handle.
        msg = _('Invalid version asked for in auth_token plugin')
        raise NotImplementedError(msg)
Example #2
0
    def get_endpoint(self, session, interface=None, version=None, **kwargs):
        """Return an endpoint for the client.

        There are no required keyword arguments to ``get_endpoint`` as a plugin
        implementation should use best effort with the information available to
        determine the endpoint.

        :param session: The session object that the auth_plugin belongs to.
        :type session: keystoneauth1.session.Session
        :param version: The version number required for this endpoint.
        :type version: tuple or str
        :param str interface: what visibility the endpoint should have.

        :returns: The base URL that will be used to talk to the required
                  service or None if not available.
        :rtype: string
        """
        if interface == plugin.AUTH_INTERFACE:
            return self._identity_uri

        if not version:
            # NOTE(jamielennox): This plugin can only be used within auth_token
            # and auth_token will always provide version= with requests.
            return None

        if not self._discover:
            self._discover = discover.Discover(session,
                                               url=self._identity_uri,
                                               authenticated=False)

        if not self._discover.url_for(version):
            # NOTE(jamielennox): The requested version is not supported by the
            # identity server.
            return None

        # NOTE(jamielennox): for backwards compatibility here we don't
        # actually use the URL from discovery we hack it up instead. :(
        # NOTE(blk-u): Normalizing the version is a workaround for bug 1450272.
        # This can be removed once that's fixed. Also fix the docstring for the
        # version parameter to be just "tuple".
        version = discover.normalize_version_number(version)
        if discover.version_match((2, 0), version):
            return '%s/v2.0' % self._identity_uri
        elif discover.version_match((3, 0), version):
            return '%s/v3' % self._identity_uri

        # NOTE(jamielennox): This plugin will only get called from auth_token
        # middleware. The middleware should never request a version that the
        # plugin doesn't know how to handle.
        msg = _('Invalid version asked for in auth_token plugin')
        raise NotImplementedError(msg)
def pick_microversion(session, required):
    """Get a new microversion if it is higher than session's default.

    :param session: The session to use for making this request.
    :type session: :class:`~keystoneauth1.adapter.Adapter`
    :param required: Version that is required for an action.
    :type required: String or tuple or None.
    :return: ``required`` as a string if the ``session``'s default is too low,
        the ``session``'s default otherwise. Returns ``None`` of both
        are ``None``.
    :raises: TypeError if ``required`` is invalid.
    """
    if required is not None:
        required = discover.normalize_version_number(required)

    if session.default_microversion is not None:
        default = discover.normalize_version_number(
            session.default_microversion)

        if required is None:
            required = default
        else:
            required = (default if discover.version_match(required, default)
                        else required)

    if required is not None:
        return discover.version_to_string(required)
Example #4
0
def pick_microversion(session, required):
    """Get a new microversion if it is higher than session's default.

    :param session: The session to use for making this request.
    :type session: :class:`~keystoneauth1.adapter.Adapter`
    :param required: Version that is required for an action.
    :type required: String or tuple or None.
    :return: ``required`` as a string if the ``session``'s default is too low,
        the ``session``'s default otherwise. Returns ``None`` of both
        are ``None``.
    :raises: TypeError if ``required`` is invalid.
    """
    if required is not None:
        required = discover.normalize_version_number(required)

    if session.default_microversion is not None:
        default = discover.normalize_version_number(
            session.default_microversion)

        if required is None:
            required = default
        else:
            required = (default if discover.version_match(required, default)
                        else required)

    if required is not None:
        return discover.version_to_string(required)
Example #5
0
    def version_data(self):
        """Get an endpoint with its versions"""
        all_version_data = []

        if not self.endpoint_with_versions:
            return None
        else:
            for endpoint in self.endpoint_with_versions:

                if not endpoint:
                    continue

                for version in endpoint:
                    if not self.desired_version:
                        if 'version' in version and version['version']:
                            all_version_data.append(version)
                        elif 'id' in version:
                            all_version_data.append(version)
                    else:
                        if 'version' in version and version['version']:
                            if self.exact_match:
                                if version['version'] == str(
                                        self.desired_version):
                                    all_version_data.append(version)
                            else:
                                current_micro_version = normalize_version_number(
                                    version['version'])
                                required_micro_version = normalize_version_number(
                                    str(self.desired_version))
                                if version_match(required_micro_version,
                                                 current_micro_version):
                                    all_version_data.append(version)
                        elif 'id' in version and version["id"]:
                            if self.exact_match:
                                if version['id'] == 'v' + str(
                                        self.desired_version):
                                    all_version_data.append(version)
                            else:
                                current_version = normalize_version_number(
                                    version['id'])
                                required_version = normalize_version_number(
                                    str(self.desired_version))
                                if version_match(required_version,
                                                 current_version):
                                    all_version_data.append(version)
            return all_version_data
Example #6
0
    def _do_create_plugin(self, session):
        plugin = None

        try:
            disc = self.get_discovery(session,
                                      self.auth_url,
                                      authenticated=False)
        except (exceptions.DiscoveryFailure,
                exceptions.HttpError,
                exceptions.ConnectionError):
            LOG.warning('Discovering versions from the identity service '
                        'failed when creating the password plugin. '
                        'Attempting to determine version from URL.')

            url_parts = urlparse.urlparse(self.auth_url)
            path = url_parts.path.lower()

            if path.startswith('/v2.0'):
                if self._has_domain_scope:
                    raise exceptions.DiscoveryFailure(
                        'Cannot use v2 authentication with domain scope')
                plugin = self.create_plugin(session, (2, 0), self.auth_url)
            elif path.startswith('/v3'):
                plugin = self.create_plugin(session, (3, 0), self.auth_url)

        else:
            disc_data = disc.version_data()

            v2_with_domain_scope = False
            for data in disc_data:
                version = data['version']

                if (discover.version_match((2,), version) and
                        self._has_domain_scope):
                    # NOTE(jamielennox): if there are domain parameters there
                    # is no point even trying against v2 APIs.
                    v2_with_domain_scope = True
                    continue

                plugin = self.create_plugin(session,
                                            version,
                                            data['url'],
                                            raw_status=data['raw_status'])

                if plugin:
                    break
            if not plugin and v2_with_domain_scope:
                raise exceptions.DiscoveryFailure(
                    'Cannot use v2 authentication with domain scope')

        if plugin:
            return plugin

        # so there were no URLs that i could use for auth of any version.
        raise exceptions.DiscoveryFailure('Could not determine a suitable URL '
                                          'for the plugin')
Example #7
0
    def create_plugin(self, session, version, url, raw_status=None):
        if discover.version_match((2,), version):
            if self._user_domain_id or self._user_domain_name:
                raise exceptions.DiscoveryFailure(
                    'Cannot use v2 authentication with domain scope')

            return v2.Password(auth_url=url,
                               user_id=self._user_id,
                               username=self._username,
                               password=self._password,
                               **self._v2_params)

        elif discover.version_match((3,), version):
            return v3.Password(auth_url=url,
                               user_id=self._user_id,
                               username=self._username,
                               user_domain_id=self._user_domain_id,
                               user_domain_name=self._user_domain_name,
                               password=self._password,
                               **self._v3_params)
Example #8
0
    def create_plugin(self, session, version, url, raw_status=None):
        if discover.version_match((2, ), version):
            if self._user_domain_id or self._user_domain_name:
                raise exceptions.DiscoveryFailure(
                    'Cannot use v2 authentication with domain scope')

            return v2.Password(auth_url=url,
                               user_id=self._user_id,
                               username=self._username,
                               password=self._password,
                               **self._v2_params)

        elif discover.version_match((3, ), version):
            return v3.Password(auth_url=url,
                               user_id=self._user_id,
                               username=self._username,
                               user_domain_id=self._user_domain_id,
                               user_domain_name=self._user_domain_name,
                               password=self._password,
                               **self._v3_params)
    def create_plugin(self, session, version, url, raw_status=None):
        if discover.version_match((2,), version):
            if self._user_domain_id or self._user_domain_name:
                # If you specify any domain parameters it won't work so quit.
                return None

            return v2.Password(auth_url=url,
                               user_id=self._user_id,
                               username=self._username,
                               password=self._password,
                               **self._v2_params)

        elif discover.version_match((3,), version):
            return v3.Password(auth_url=url,
                               user_id=self._user_id,
                               username=self._username,
                               user_domain_id=self._user_domain_id,
                               user_domain_name=self._user_domain_name,
                               password=self._password,
                               **self._v3_params)
Example #10
0
    def create_plugin(self, session, version, url, raw_status=None):
        if discover.version_match((2,), version):
            if self._user_domain_id or self._user_domain_name:
                return None

            return v2.Password(auth_url=url,
                               user_id=self._user_id,
                               username=self._username,
                               password=self._password,
                               **self._v2_params)

        elif discover.version_match((3,), version):
            u_domain_id = self._user_domain_id or self._default_domain_id
            u_domain_name = self._user_domain_name or self._default_domain_name

            return v3.Password(auth_url=url,
                               user_id=self._user_id,
                               username=self._username,
                               user_domain_id=u_domain_id,
                               user_domain_name=u_domain_name,
                               password=self._password,
                               **self._v3_params)
Example #11
0
    def create_plugin(self, session, version, url, raw_status=None):
        if discover.version_match((2, ), version):
            if self._user_domain_id or self._user_domain_name:
                return None

            return v2.Password(auth_url=url,
                               user_id=self._user_id,
                               username=self._username,
                               password=self._password,
                               **self._v2_params)

        elif discover.version_match((3, ), version):
            u_domain_id = self._user_domain_id or self._default_domain_id
            u_domain_name = self._user_domain_name or self._default_domain_name

            return v3.Password(auth_url=url,
                               user_id=self._user_id,
                               username=self._username,
                               user_domain_id=u_domain_id,
                               user_domain_name=u_domain_name,
                               password=self._password,
                               **self._v3_params)
Example #12
0
def supports_microversion(adapter, microversion, raise_exception=False):
    """Determine if the given adapter supports the given microversion.

    Checks the min and max microversion asserted by the service and checks to
    make sure that ``min <= microversion <= max``. Current default microversion
    is taken into consideration if set and verifies that ``microversion <=
    default``.

    :param adapter: :class:`~keystoneauth1.adapter.Adapter` instance.
    :param str microversion: String containing the desired microversion.
    :param bool raise_exception: Raise exception when requested microversion
        is not supported be the server side or is higher than the current
        default microversion.
    :returns: True if the service supports the microversion.
    :rtype: bool
    :raises: :class:`~openstack.exceptions.SDKException` when requested
        microversion is not supported.
    """

    endpoint_data = adapter.get_endpoint_data()
    if (endpoint_data.min_microversion
            and endpoint_data.max_microversion and discover.version_between(
                endpoint_data.min_microversion, endpoint_data.max_microversion,
                microversion)):
        if adapter.default_microversion is not None:
            # If default_microversion is set - evaluate
            # whether it match the expectation
            candidate = discover.normalize_version_number(
                adapter.default_microversion)
            required = discover.normalize_version_number(microversion)
            supports = discover.version_match(required, candidate)
            if raise_exception and not supports:
                raise exceptions.SDKException(
                    'Required microversion {ver} is higher than currently '
                    'selected {curr}'.format(
                        ver=microversion, curr=adapter.default_microversion))
            return supports
        return True
    if raise_exception:
        raise exceptions.SDKException(
            'Required microversion {ver} is not supported '
            'by the server side'.format(ver=microversion))
    return False
Example #13
0
    def _get_strategy_class(self):
        if self._requested_auth_version:
            # A specific version was requested.
            if discover.version_match(_V3RequestStrategy.AUTH_VERSION, self._requested_auth_version):
                return _V3RequestStrategy

            # The version isn't v3 so we don't know what to do. Just assume V2.
            return _V2RequestStrategy

        # Specific version was not requested then we fall through to
        # discovering available versions from the server
        for klass in _REQUEST_STRATEGIES:
            if self._adapter.get_endpoint(version=klass.AUTH_VERSION):
                self._LOG.debug("Auth Token confirmed use of %s apis", self._requested_auth_version)
                return klass

        versions = ["v%d.%d" % s.AUTH_VERSION for s in _REQUEST_STRATEGIES]
        self._LOG.error(_LE("No attempted versions [%s] supported by server"), ", ".join(versions))

        msg = _("No compatible apis supported by server")
        raise ksm_exceptions.ServiceError(msg)
Example #14
0
    def _get_strategy_class(self):
        if self._requested_auth_version:
            if not discover.version_match(_V3RequestStrategy.AUTH_VERSION,
                                          self._requested_auth_interface):
                self._LOG.info('A version other than v3 was requested: %s',
                               self._requested_auth_interface)
            # Return v3, even if the request is unknown
            return _V3RequestStrategy

        # Specific version was not requested then we fall through to
        # discovering available versions from the server
        for klass in _REQUEST_STRATEGIES:
            if self._adapter.get_endpoint(version=klass.AUTH_VERSION):
                self._LOG.debug('Auth Token confirmed use of %s apis',
                                klass.AUTH_VERSION)
                return klass

        versions = ['v%d.%d' % s.AUTH_VERSION for s in _REQUEST_STRATEGIES]
        self._LOG.error('No attempted versions [%s] supported by server',
                        ', '.join(versions))

        msg = _('No compatible apis supported by server')
        raise ksm_exceptions.ServiceError(msg)
Example #15
0
    def _get_strategy_class(self):
        if self._requested_auth_version:
            # A specific version was requested.
            if discover.version_match(_V3RequestStrategy.AUTH_VERSION,
                                      self._requested_auth_version):
                return _V3RequestStrategy

            # The version isn't v3 so we don't know what to do. Just assume V2.
            return _V2RequestStrategy

        # Specific version was not requested then we fall through to
        # discovering available versions from the server
        for klass in _REQUEST_STRATEGIES:
            if self._adapter.get_endpoint(version=klass.AUTH_VERSION):
                self._LOG.debug('Auth Token confirmed use of %s apis',
                                self._requested_auth_version)
                return klass

        versions = ['v%d.%d' % s.AUTH_VERSION for s in _REQUEST_STRATEGIES]
        self._LOG.error(_LE('No attempted versions [%s] supported by server'),
                        ', '.join(versions))

        msg = _('No compatible apis supported by server')
        raise ksm_exceptions.ServiceError(msg)
Example #16
0
    def _do_create_plugin(self, session):
        plugin = None

        try:
            disc = self.get_discovery(session,
                                      self.auth_url,
                                      authenticated=False)
        except (exceptions.DiscoveryFailure,
                exceptions.HttpError,
                exceptions.ConnectionError):
            LOG.warning('Discovering versions from the identity service '
                        'failed when creating the password plugin. '
                        'Attempting to determine version from URL.')

            url_parts = urlparse.urlparse(self.auth_url)
            path = url_parts.path.lower()

            if path.startswith('/v2.0'):
                if self._has_domain_scope:
                    raise exceptions.DiscoveryFailure(
                        'Cannot use v2 authentication with domain scope')
                plugin = self.create_plugin(session, (2, 0), self.auth_url)
            elif path.startswith('/v3'):
                plugin = self.create_plugin(session, (3, 0), self.auth_url)

        else:
            # NOTE(jamielennox): version_data is always in oldest to newest
            # order. This is fine normally because we explicitly skip v2 below
            # if there is domain data present. With default_domain params
            # though we want a v3 plugin if available and fall back to v2 so we
            # have to process in reverse order.  FIXME(jamielennox): if we ever
            # go for another version we should reverse this logic as we always
            # want to favour the newest available version.
            reverse = self._default_domain_id or self._default_domain_name
            disc_data = disc.version_data(reverse=bool(reverse))

            v2_with_domain_scope = False
            for data in disc_data:
                version = data['version']

                if (discover.version_match((2,), version) and
                        self._has_domain_scope):
                    # NOTE(jamielennox): if there are domain parameters there
                    # is no point even trying against v2 APIs.
                    v2_with_domain_scope = True
                    continue

                plugin = self.create_plugin(session,
                                            version,
                                            data['url'],
                                            raw_status=data['raw_status'])

                if plugin:
                    break
            if not plugin and v2_with_domain_scope:
                raise exceptions.DiscoveryFailure(
                    'Cannot use v2 authentication with domain scope')

        if plugin:
            return plugin

        # so there were no URLs that i could use for auth of any version.
        raise exceptions.DiscoveryFailure('Could not determine a suitable URL '
                                          'for the plugin')
Example #17
0
    def create_plugin(self, session, version, url, raw_status=None):
        if discover.version_match((2,), version):
            return v2.Token(url, self._token, **self._v2_params)

        elif discover.version_match((3,), version):
            return v3.Token(url, self._token, **self._v3_params)
Example #18
0
    def create_plugin(self, session, version, url, raw_status=None):
        if discover.version_match((2, ), version):
            return v2.Token(url, self._token, **self._v2_params)

        elif discover.version_match((3, ), version):
            return v3.Token(url, self._token, **self._v3_params)