diff options
author | Jamie Lennox <jamielennox@redhat.com> | 2014-08-25 16:11:16 +1000 |
---|---|---|
committer | Jamie Lennox <jamielennox@redhat.com> | 2014-09-02 12:38:03 +1000 |
commit | 84af49ce97f481731939344c9c45752ea62db5af (patch) | |
tree | c5558edf95a44b3f97902a6909bb04fc651c3732 | |
parent | 8e87c0b600d0742fbdd69ab770dbeb9dca7cf58c (diff) | |
download | python-cinderclient-84af49ce97f481731939344c9c45752ea62db5af.tar.gz |
Use adapter from keystoneclient
The keystoneclient provides an adapter which maintains the client state
around the session. We should re-use this rather than copy it and it
also means we will get new adapter functions and parameters as they
become available.
Change-Id: I05c0d650dcdd69f7e77a06563d735efe521a41ae
-rw-r--r-- | cinderclient/client.py | 226 | ||||
-rw-r--r-- | cinderclient/v1/client.py | 13 | ||||
-rw-r--r-- | cinderclient/v2/client.py | 14 |
3 files changed, 110 insertions, 143 deletions
diff --git a/cinderclient/client.py b/cinderclient/client.py index d1dbe18..a436841 100644 --- a/cinderclient/client.py +++ b/cinderclient/client.py @@ -22,14 +22,15 @@ from __future__ import print_function import logging +from keystoneclient import access +from keystoneclient import adapter +from keystoneclient.auth.identity import base +import requests + from cinderclient import exceptions from cinderclient.openstack.common import strutils from cinderclient import utils -from keystoneclient import access -from keystoneclient.auth.identity import v3 as v3_auth -import requests - try: import urlparse @@ -51,117 +52,90 @@ if not hasattr(urlparse, 'parse_qsl'): import cgi urlparse.parse_qsl = cgi.parse_qsl +_VALID_VERSIONS = ['v1', 'v2'] -class CinderClientMixin(object): - def get_volume_api_version_from_endpoint(self): - magic_tuple = urlparse.urlsplit(self.management_url) - scheme, netloc, path, query, frag = magic_tuple - components = path.split("/") - valid_versions = ['v1', 'v2'] - for version in valid_versions: - if version in components: - return version[1:] - msg = "Invalid client version '%s'. must be one of: %s" % ( - (version, ', '.join(valid_versions))) - raise exceptions.UnsupportedVersion(msg) +def get_volume_api_from_url(url): + scheme, netloc, path, query, frag = urlparse.urlsplit(url) + components = path.split("/") + for version in _VALID_VERSIONS: + if version in components: + return version[1:] -class SessionClient(CinderClientMixin): + msg = "Invalid client version '%s'. must be one of: %s" % ( + (version, ', '.join(valid_versions))) + raise exceptions.UnsupportedVersion(msg) - def __init__(self, session, auth, interface=None, - service_type=None, service_name=None, - region_name=None, http_log_debug=False): - self.session = session - self.auth = auth - - self.interface = interface - self.service_type = service_type - self.service_name = service_name - self.region_name = region_name - self.auth_token = None - self.endpoint_url = None - self.management_url = self.endpoint_url - self.http_log_debug = http_log_debug - self._logger = logging.getLogger(__name__) - if self.http_log_debug: - # Use keystoneclient's logs instead of writing our own - ks_logger = logging.getLogger("keystoneclient") - ks_logger.setLevel(logging.DEBUG) +class SessionClient(adapter.LegacyJsonAdapter): - def request(self, url, method, **kwargs): + def __init__(self, **kwargs): kwargs.setdefault('user_agent', 'python-cinderclient') - kwargs.setdefault('auth', self.auth) - kwargs.setdefault('authenticated', False) - - try: - kwargs['json'] = kwargs.pop('body') - except KeyError: - pass - - endpoint_filter = kwargs.setdefault('endpoint_filter', {}) - endpoint_filter.setdefault('interface', self.interface) - endpoint_filter.setdefault('service_type', self.service_type) - endpoint_filter.setdefault('service_name', self.service_name) - endpoint_filter.setdefault('region_name', self.region_name) - - resp = self.session.request(url, method, **kwargs) - - body = None - if resp.text: - try: - body = resp.json() - except ValueError: - pass + kwargs.setdefault('service_type', 'volume') + super(SessionClient, self).__init__(**kwargs) - return resp, body + def request(self, *args, **kwargs): + kwargs.setdefault('authenticated', False) + return super(SessionClient, self).request(*args, **kwargs) def _cs_request(self, url, method, **kwargs): # this function is mostly redundant but makes compatibility easier kwargs.setdefault('authenticated', True) return self.request(url, method, **kwargs) - def do_request(self, url, method, **kwargs): - # this function is mostly redundant but makes compatibility easier - kwargs.setdefault('headers', {}) - if self.auth_token is None: - self.authenticate() - kwargs['headers']['X-Auth-Token'] = self.auth_token - if self.access_info is not None: - kwargs['headers'][ - 'X-Auth-Project-Id'] = self.access_info.project_id - - resp, body = self._cs_request( - self.endpoint_url + url, method, **kwargs) - return resp, body - - def authenticate(self): - self.auth_token = self.session.get_token(self.auth) - self.access_info = self.session.auth.get_access(self.session) - - self.endpoint_url = self.session.get_endpoint( - self.auth, - service_type=self.service_type, - region_name=self.region_name, - interface=self.interface) - self.management_url = self.endpoint_url - self.service_catalog = self.access_info.service_catalog - def get(self, url, **kwargs): - return self.do_request(url, 'GET', **kwargs) + return self._cs_request(url, 'GET', **kwargs) def post(self, url, **kwargs): - return self.do_request(url, 'POST', **kwargs) + return self._cs_request(url, 'POST', **kwargs) def put(self, url, **kwargs): - return self.do_request(url, 'PUT', **kwargs) + return self._cs_request(url, 'PUT', **kwargs) def delete(self, url, **kwargs): - return self.do_request(url, 'DELETE', **kwargs) + return self._cs_request(url, 'DELETE', **kwargs) + def _invalidate(self, auth=None): + # NOTE(jamielennox): This is being implemented in keystoneclient + return self.session.invalidate(auth or self.auth) + + def _get_token(self, auth=None): + # NOTE(jamielennox): This is being implemented in keystoneclient + return self.session.get_token(auth or self.auth) + + def _get_endpoint(self, auth=None, **kwargs): + # NOTE(jamielennox): This is being implemented in keystoneclient + if self.service_type: + kwargs.setdefault('service_type', self.service_type) + if self.service_name: + kwargs.setdefault('service_name', self.service_name) + if self.interface: + kwargs.setdefault('interface', self.interface) + if self.region_name: + kwargs.setdefault('region_name', self.region_name) + return self.session.get_endpoint(auth or self.auth, **kwargs) -class HTTPClient(CinderClientMixin): + def get_volume_api_version_from_endpoint(self): + return get_volume_api_from_url(self._get_endpoint()) + + def authenticate(self, auth=None): + self._invalidate(auth) + return self._get_token(auth) + + @property + def service_catalog(self): + # NOTE(jamielennox): This is ugly and should be deprecated. + auth = self.auth or self.session.auth + + if isinstance(auth, base.BaseIdentityPlugin): + return auth.get_access(self.session).service_catalog + + raise AttributeError('There is no service catalog for this type of ' + 'auth plugin.') + + +class HTTPClient(object): USER_AGENT = 'python-cinderclient' @@ -336,6 +310,9 @@ class HTTPClient(CinderClientMixin): def delete(self, url, **kwargs): return self._cs_request(url, 'DELETE', **kwargs) + def get_volume_api_version_from_endpoint(self): + return get_volume_api_from_url(self.management_url) + def _extract_service_catalog(self, url, resp, body, extract_token=True): """See what the auth service told us and process the response. We may get redirected to another site, fail or actually get @@ -504,51 +481,40 @@ def _construct_http_client(username=None, password=None, project_id=None, auth_system='keystone', auth_plugin=None, cacert=None, tenant_id=None, session=None, - auth=None): - - # Don't use sessions if third party plugin is used - if session and not auth_plugin: - - # If auth pluggin is specified use that pluggin - session.auth = auth or session.auth - - if isinstance(session.auth, v3_auth.Password): - # In v3 and v2 interace names are different - interface_map = {"publicURL": "public", - "adminURL": "admin"} - - endpoint_type = interface_map[endpoint_type] + auth=None, + **kwargs): + if session: + kwargs.setdefault('interface', endpoint_type) return SessionClient(session=session, auth=auth, - interface=endpoint_type, service_type=service_type, service_name=service_name, region_name=region_name, - http_log_debug=http_log_debug) - - # FIXME(jamielennox): username and password are now optional. Need - # to test that they were provided in this mode. - return HTTPClient(username, - password, - projectid=project_id, - auth_url=auth_url, - insecure=insecure, - timeout=timeout, - tenant_id=tenant_id, - proxy_token=proxy_token, - proxy_tenant_id=proxy_tenant_id, - region_name=region_name, - endpoint_type=endpoint_type, - service_type=service_type, - service_name=service_name, - volume_service_name=volume_service_name, - retries=retries, - http_log_debug=http_log_debug, - cacert=cacert, - auth_system=auth_system, - auth_plugin=auth_plugin, - ) + **kwargs) + else: + # FIXME(jamielennox): username and password are now optional. Need + # to test that they were provided in this mode. + return HTTPClient(username, + password, + projectid=project_id, + auth_url=auth_url, + insecure=insecure, + timeout=timeout, + tenant_id=tenant_id, + proxy_token=proxy_token, + proxy_tenant_id=proxy_tenant_id, + region_name=region_name, + endpoint_type=endpoint_type, + service_type=service_type, + service_name=service_name, + volume_service_name=volume_service_name, + retries=retries, + http_log_debug=http_log_debug, + cacert=cacert, + auth_system=auth_system, + auth_plugin=auth_plugin, + ) def get_client_class(version): diff --git a/cinderclient/v1/client.py b/cinderclient/v1/client.py index 9b375b8..c11a954 100644 --- a/cinderclient/v1/client.py +++ b/cinderclient/v1/client.py @@ -44,14 +44,14 @@ class Client(object): """ - def __init__(self, username, api_key, project_id=None, auth_url='', - insecure=False, timeout=None, tenant_id=None, + def __init__(self, username=None, api_key=None, project_id=None, + auth_url='', insecure=False, timeout=None, tenant_id=None, proxy_tenant_id=None, proxy_token=None, region_name=None, endpoint_type='publicURL', extensions=None, service_type='volume', service_name=None, - volume_service_name=None, retries=None, - http_log_debug=False, cacert=None, - auth_system='keystone', auth_plugin=None, session=None): + volume_service_name=None, retries=None, http_log_debug=False, + cacert=None, auth_system='keystone', auth_plugin=None, + session=None, **kwargs): # FIXME(comstud): Rename the api_key argument above when we # know it's not being used as keyword argument password = api_key @@ -100,7 +100,8 @@ class Client(object): cacert=cacert, auth_system=auth_system, auth_plugin=auth_plugin, - session=session) + session=session, + **kwargs) def authenticate(self): """ diff --git a/cinderclient/v2/client.py b/cinderclient/v2/client.py index a4016db..a7edfbb 100644 --- a/cinderclient/v2/client.py +++ b/cinderclient/v2/client.py @@ -42,15 +42,14 @@ class Client(object): ... """ - def __init__(self, username, api_key, project_id=None, auth_url='', - insecure=False, timeout=None, tenant_id=None, + def __init__(self, username=None, api_key=None, project_id=None, + auth_url='', insecure=False, timeout=None, tenant_id=None, proxy_tenant_id=None, proxy_token=None, region_name=None, endpoint_type='publicURL', extensions=None, service_type='volumev2', service_name=None, - volume_service_name=None, retries=None, - http_log_debug=False, cacert=None, - auth_system='keystone', auth_plugin=None, - session=None): + volume_service_name=None, retries=None, http_log_debug=False, + cacert=None, auth_system='keystone', auth_plugin=None, + session=None, **kwargs): # FIXME(comstud): Rename the api_key argument above when we # know it's not being used as keyword argument password = api_key @@ -99,7 +98,8 @@ class Client(object): cacert=cacert, auth_system=auth_system, auth_plugin=auth_plugin, - session=session) + session=session, + **kwargs) def authenticate(self): """Authenticate against the server. |