예제 #1
0
    def __init__(self, session=None, authenticated=None, **kwargs):
        if not session:
            warnings.warn(
                'Constructing a Discover instance without using a session is '
                'deprecated as of the 1.7.0 release and may be removed in the '
                '2.0.0 release.', DeprecationWarning)
            session = client_session.Session._construct(kwargs)
        kwargs['session'] = session

        url = None
        endpoint = kwargs.pop('endpoint', None)
        auth_url = kwargs.pop('auth_url', None)

        if endpoint:
            self._use_endpoint = True
            url = endpoint
        elif auth_url:
            self._use_endpoint = False
            url = auth_url
        elif session.auth:
            self._use_endpoint = False
            url = session.get_endpoint(interface=plugin.AUTH_INTERFACE)

        if not url:
            raise exceptions.DiscoveryFailure(
                _('Not enough information to determine URL. Provide'
                  ' either a Session, or auth_url or endpoint'))

        self._client_kwargs = kwargs
        super(Discover, self).__init__(session,
                                       url,
                                       authenticated=authenticated)
예제 #2
0
    def _get_factory_from_response_entry(self, version_data, **kwargs):
        """Create a _KeystoneVersion factory object from a version response
        entry returned from a server.
        """
        try:
            version_str = version_data['id']
            status = version_data['status']

            if not version_str.startswith('v'):
                raise exceptions.DiscoveryFailure('Skipping over invalid '
                                                  'version string: %s. It '
                                                  'should start with a v.' %
                                                  version_str)

            for link in version_data['links']:
                # NOTE(jamielennox): there are plenty of links like with
                # documentation and such, we only care about the self
                # which is a link to the URL we should use.
                if link['rel'].lower() == 'self':
                    version_number = _normalize_version_number(version_str)
                    version_url = link['href']
                    break
            else:
                raise exceptions.DiscoveryFailure("Didn't find any links "
                                                  "in version data.")

        except (KeyError, TypeError, ValueError):
            raise exceptions.DiscoveryFailure('Skipping over invalid '
                                              'version data.')

        # NOTE(jamielennox): the url might be the auth_url or the endpoint
        # depending on what was passed initially. Order is important, endpoint
        # needs to override auth_url.
        for url_type in ('auth_url', 'endpoint'):
            if self._client_kwargs.get(url_type, False):
                kwargs[url_type] = version_url
            else:
                kwargs[url_type] = None

        return _KeystoneVersion(status=status,
                                version=version_number,
                                **kwargs)
예제 #3
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.warn(_LW('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') and not self._has_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()

            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.
                    continue

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

                if plugin:
                    break

        if plugin:
            return plugin

        # so there were no URLs that i could use for auth of any version.
        msg = _('Could not determine a suitable URL for the plugin')
        raise exceptions.DiscoveryFailure(msg)
예제 #4
0
    def __init__(self, version, status, client_class=None, **kwargs):
        """Create a new discovered version object.

        :param tuple version: the version of the available API.
        :param string status: the stability of the API.
        :param Class client_class: the client class that should be used to
                                   instantiate against this version of the API.
                                   (optional, will be matched against known)
        :param dict **kwargs: Additional arguments that should be passed on to
                              the client when it is constructed.
        """
        self.version = version
        self.status = status
        self.client_class = client_class
        self.client_kwargs = kwargs

        if not self.client_class:
            try:
                self.client_class = self._CLIENT_VERSIONS[self.version[0]]
            except KeyError:
                raise exceptions.DiscoveryFailure("No client available "
                                                  "for version: %s" %
                                                  self.version)
예제 #5
0
    def _create_client(self, version_data, **kwargs):
        # Get the client for the version requested that was returned
        try:
            client_class = _CLIENT_VERSIONS[version_data['version'][0]]
        except KeyError:
            version = '.'.join(str(v) for v in version_data['version'])
            msg = _('No client available for version: %s') % version
            raise exceptions.DiscoveryFailure(msg)

        # kwargs should take priority over stored kwargs.
        for k, v in six.iteritems(self._client_kwargs):
            kwargs.setdefault(k, v)

        # restore the url to either auth_url or endpoint depending on what
        # was initially given
        if self._use_endpoint:
            kwargs['auth_url'] = None
            kwargs['endpoint'] = version_data['url']
        else:
            kwargs['auth_url'] = version_data['url']
            kwargs['endpoint'] = None

        return client_class(**kwargs)
예제 #6
0
def get_version_data(session, url, authenticated=None):
    """Retrieve raw version data from a url."""
    headers = {'Accept': 'application/json'}

    resp = session.get(url, headers=headers, authenticated=authenticated)

    try:
        body_resp = resp.json()
    except ValueError:  # nosec(cjschaef): raise a DiscoveryFailure below
        pass
    else:
        # In the event of querying a root URL we will get back a list of
        # available versions.
        try:
            return body_resp['versions']['values']
        except (KeyError, TypeError):  # nosec(cjschaef): attempt to return
            # versions dict or query the endpoint or raise a DiscoveryFailure
            pass

        # Most servers don't have a 'values' element so accept a simple
        # versions dict if available.
        try:
            return body_resp['versions']
        except KeyError:  # nosec(cjschaef): query the endpoint or raise a
            # DiscoveryFailure
            pass

        # Otherwise if we query an endpoint like /v2.0 then we will get back
        # just the one available version.
        try:
            return [body_resp['version']]
        except KeyError:  # nosec(cjschaef): raise a DiscoveryFailure
            pass

    err_text = resp.text[:50] + '...' if len(resp.text) > 50 else resp.text
    msg = _('Invalid Response - Bad version data returned: %s') % err_text
    raise exceptions.DiscoveryFailure(msg)
예제 #7
0
def available_versions(url, session=None, **kwargs):
    headers = {'Accept': 'application/json'}

    if not session:
        session = client_session.Session.construct(kwargs)

    resp = session.get(url, headers=headers)

    try:
        body_resp = resp.json()
    except ValueError:
        pass
    else:
        # In the event of querying a root URL we will get back a list of
        # available versions.
        try:
            return body_resp['versions']['values']
        except (KeyError, TypeError):
            pass

        # Most servers don't have a 'values' element so accept a simple
        # versions dict if available.
        try:
            return body_resp['versions']
        except KeyError:
            pass

        # Otherwise if we query an endpoint like /v2.0 then we will get back
        # just the one available version.
        try:
            return [body_resp['version']]
        except KeyError:
            pass

    raise exceptions.DiscoveryFailure("Invalid Response - Bad version"
                                      " data returned: %s" % resp.text)
예제 #8
0
    def __init__(self, session=None, authenticated=None, **kwargs):
        if not session:
            session = client_session.Session.construct(kwargs)
        kwargs['session'] = session

        url = None
        endpoint = kwargs.pop('endpoint', None)
        auth_url = kwargs.pop('auth_url', None)

        if endpoint:
            self._use_endpoint = True
            url = endpoint
        elif auth_url:
            self._use_endpoint = False
            url = auth_url

        if not url:
            raise exceptions.DiscoveryFailure(
                _('Not enough information to determine URL. Provide either '
                  'auth_url or endpoint'))

        self._client_kwargs = kwargs
        super(Discover, self).__init__(session, url,
                                       authenticated=authenticated)
예제 #9
0
    def __init__(self, session=None, **kwargs):
        """Construct a new discovery object.

        The connection parameters associated with this method are the same
        format and name as those used by a client (see
        keystoneclient.v2_0.client.Client and keystoneclient.v3.client.Client).
        If not overridden in subsequent methods they will also be what is
        passed to the constructed client.

        In the event that auth_url and endpoint is provided then auth_url will
        be used in accordance with how the client operates.

        The initialization process also queries the server.

        :param Session session: A session object that will be used for
                                communication. Clients will also be constructed
                                with this session.
        :param string auth_url: Identity service endpoint for authorization.
                                (optional)
        :param string endpoint: A user-supplied endpoint URL for the identity
                                service. (optional)
        :param string original_ip: The original IP of the requesting user
                                   which will be sent to identity service in a
                                   'Forwarded' header. (optional)
                                   DEPRECATED: use the session object. This is
                                   ignored if a session is provided.
        :param boolean debug: Enables debug logging of all request and
                              responses to the identity service.
                              default False (optional)
                              DEPRECATED: use the session object. This is
                              ignored if a session is provided.
        :param string cacert: Path to the Privacy Enhanced Mail (PEM) file
                              which contains the trusted authority X.509
                              certificates needed to established SSL connection
                              with the identity service. (optional)
                              DEPRECATED: use the session object. This is
                              ignored if a session is provided.
        :param string key: Path to the Privacy Enhanced Mail (PEM) file which
                           contains the unencrypted client private key needed
                           to established two-way SSL connection with the
                           identity service. (optional)
                           DEPRECATED: use the session object. This is
                           ignored if a session is provided.
        :param string cert: Path to the Privacy Enhanced Mail (PEM) file which
                            contains the corresponding X.509 client certificate
                            needed to established two-way SSL connection with
                            the identity service. (optional)
                            DEPRECATED: use the session object. This is
                            ignored if a session is provided.
        :param boolean insecure: Does not perform X.509 certificate validation
                                 when establishing SSL connection with identity
                                 service. default: False (optional)
                                 DEPRECATED: use the session object. This is
                                 ignored if a session is provided.
        """

        if not session:
            session = client_session.Session.construct(kwargs)
        kwargs['session'] = session

        url = kwargs.get('endpoint') or kwargs.get('auth_url')
        if not url:
            raise exceptions.DiscoveryFailure('Not enough information to '
                                              'determine URL. Provide either '
                                              'auth_url or endpoint')

        self._client_kwargs = kwargs
        self._available_versions = available_versions(url, session=session)
예제 #10
0
 def url_for(self, version):
     raise ks_exc.DiscoveryFailure()