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)
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)
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)
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)
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)
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)
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)
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)
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)
def url_for(self, version): raise ks_exc.DiscoveryFailure()