summaryrefslogtreecommitdiff
path: root/troveclient/client.py
diff options
context:
space:
mode:
authordaniel-a-nguyen <dan.nguyens.mail@gmail.com>2014-06-24 11:34:51 -0700
committerBob Thyne <bob.thyne@hp.com>2014-11-05 15:54:16 -0800
commit3c47a1855b7ee1345dadfb00ae90a6279b7c424e (patch)
tree7762d0d5ca52ac6d8079ef8ff24b294f56cd403c /troveclient/client.py
parentd596428b413764a14672409875efb9a130261e90 (diff)
downloadpython-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.py105
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():