diff options
author | daniel-a-nguyen <dan.nguyens.mail@gmail.com> | 2014-06-24 11:34:51 -0700 |
---|---|---|
committer | Bob Thyne <bob.thyne@hp.com> | 2014-11-05 15:54:16 -0800 |
commit | 3c47a1855b7ee1345dadfb00ae90a6279b7c424e (patch) | |
tree | 7762d0d5ca52ac6d8079ef8ff24b294f56cd403c /troveclient/client.py | |
parent | d596428b413764a14672409875efb9a130261e90 (diff) | |
download | python-troveclient-3c47a1855b7ee1345dadfb00ae90a6279b7c424e.tar.gz |
Adds support for Keystone V3 API
Updated trove client to support Keystone V3 API. The
Keystoneclient session object is used for authentication, retrieving
the service catalog and HTTP connection/session management.
Added additional CLI parameters for Keystone V3.
Change-Id: I800c252234be2ff11d818cf7513c61c5431eb15c
Closes-Bug: 1323866
Diffstat (limited to 'troveclient/client.py')
-rw-r--r-- | troveclient/client.py | 105 |
1 files changed, 92 insertions, 13 deletions
diff --git a/troveclient/client.py b/troveclient/client.py index 25a2235..8280ae2 100644 --- a/troveclient/client.py +++ b/troveclient/client.py @@ -25,6 +25,7 @@ import logging import os import requests +from keystoneclient import adapter from troveclient.openstack.common.apiclient import client from troveclient.openstack.common.apiclient import exceptions from troveclient import service_catalog @@ -50,7 +51,21 @@ if not hasattr(urlparse, 'parse_qsl'): urlparse.parse_qsl = cgi.parse_qsl -class HTTPClient(object): +class TroveClientMixin(object): + + def get_database_api_version_from_endpoint(self): + magic_tuple = urlparse.urlsplit(self.management_url) + scheme, netloc, path, query, frag = magic_tuple + v = path.split("/")[1] + valid_versions = ['v1.0'] + if v not in valid_versions: + msg = "Invalid client version '%s'. must be one of: %s" % ( + (v, ', '.join(valid_versions))) + raise exceptions.UnsupportedVersion(msg) + return v[1:] + + +class HTTPClient(TroveClientMixin): USER_AGENT = 'python-troveclient' @@ -59,7 +74,17 @@ class HTTPClient(object): proxy_token=None, region_name=None, endpoint_type='publicURL', service_type=None, service_name=None, database_service_name=None, retries=None, - http_log_debug=False, cacert=None, bypass_url=None): + http_log_debug=False, cacert=None, bypass_url=None, + auth_system='keystone', auth_plugin=None): + + if auth_system and auth_system != 'keystone' and not auth_plugin: + raise exceptions.AuthSystemNotFound(auth_system) + + if not auth_url and auth_system and auth_system != 'keystone': + auth_url = auth_plugin.get_auth_url() + if not auth_url: + raise exceptions.EndpointNotFound() + self.user = user self.password = password self.projectid = projectid @@ -89,6 +114,9 @@ class HTTPClient(object): else: self.verify_cert = True + self.auth_system = auth_system + self.auth_plugin = auth_plugin + self._logger = logging.getLogger(__name__) if self.http_log_debug and not self._logger.handlers: ch = logging.StreamHandler() @@ -251,7 +279,6 @@ class HTTPClient(object): except exceptions.EndpointNotFound: print("Could not find any suitable endpoint. Correct region?") raise - elif resp.status_code == 305: return resp['location'] else: @@ -313,6 +340,7 @@ class HTTPClient(object): # with the endpoints any more, we need to replace # our service account token with the user token. self.auth_token = self.proxy_token + else: try: while auth_url: @@ -388,16 +416,67 @@ class HTTPClient(object): return self._extract_service_catalog(url, resp, body) - def get_database_api_version_from_endpoint(self): - magic_tuple = urlparse.urlsplit(self.management_url) - scheme, netloc, path, query, frag = magic_tuple - v = path.split("/")[1] - valid_versions = ['v1.0'] - if v not in valid_versions: - msg = "Invalid client version '%s'. must be one of: %s" % ( - (v, ', '.join(valid_versions))) - raise exceptions.UnsupportedVersion(msg) - return v[1:] + +class SessionClient(adapter.LegacyJsonAdapter): + + def request(self, url, method, **kwargs): + # NOTE(jamielennox): The standard call raises errors from + # keystoneclient, where we need to raise the novaclient errors. + raise_exc = kwargs.pop('raise_exc', True) + resp, body = super(SessionClient, self).request(url, + method, + raise_exc=False, + **kwargs) + + if raise_exc and resp.status_code >= 400: + raise exceptions.from_response(resp, body, url, method) + + return resp, body + + +def _construct_http_client(username=None, password=None, project_id=None, + auth_url=None, insecure=False, timeout=None, + proxy_tenant_id=None, proxy_token=None, + region_name=None, endpoint_type='publicURL', + service_type='database', + service_name=None, database_service_name=None, + retries=None, + http_log_debug=False, + auth_system='keystone', auth_plugin=None, + cacert=None, tenant_id=None, + session=None, + auth=None): + if session: + 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, + database_service_name=database_service_name, + retries=retries, + http_log_debug=http_log_debug, + cacert=cacert, + auth_system=auth_system, + auth_plugin=auth_plugin, + ) def get_version_map(): |