From 5b81006c54c755a01a82b19f8fd80bf976cc322d Mon Sep 17 00:00:00 2001 From: Endre Karlson Date: Thu, 4 Sep 2014 17:14:12 +0200 Subject: [PATCH] Use keystone sessions for v1 client This removes the code for checking if the service catalog has a version part in the url or not aka /v1 and removing it as it's handled by the underlying ksclient code in sessions. It also removes old authentication code. Change-Id: I04109a935d7d94518c7dab05122a64ef37190d44 --- designateclient/utils.py | 47 -------------- designateclient/v1/__init__.py | 114 ++++++++++++++++----------------- 2 files changed, 56 insertions(+), 105 deletions(-) diff --git a/designateclient/utils.py b/designateclient/utils.py index a5a1700..33de29e 100644 --- a/designateclient/utils.py +++ b/designateclient/utils.py @@ -18,12 +18,7 @@ import json import os -from keystoneclient import client as ksclient -from keystoneclient.exceptions import DiscoveryFailure -from keystoneclient.v2_0 import client as v2_ksclient -from keystoneclient.v3 import client as v3_ksclient import pkg_resources -import six.moves.urllib.parse as urlparse from designateclient import exceptions @@ -97,45 +92,3 @@ def get_columns(data): map(lambda item: map(_seen, item.keys()), data) return list(columns) - - -def get_ksclient(username=None, user_id=None, user_domain_id=None, - user_domain_name=None, password=None, tenant_id=None, - tenant_name=None, domain_id=None, domain_name=None, - project_id=None, project_name=None, - project_domain_id=None, project_domain_name=None, - auth_url=None, token=None, insecure=None): - kwargs = { - 'username': username, - 'user_domain_id': user_domain_id, - 'user_domain_name': user_domain_name, - 'password': password, - 'tenant_id': tenant_id, - 'tenant_name': tenant_name, - 'domain_id': domain_id, - 'domain_name': domain_name, - 'project_id': project_id, - 'project_name': project_name, - 'project_domain_id': project_domain_id, - 'project_domain_name': project_domain_name, - 'auth_url': auth_url, - 'token': token, - 'insecure': insecure - } - - try: - return ksclient.Client(**kwargs) - except DiscoveryFailure: - # Discovery response mismatch. Raise the error - raise - except Exception: - # Some public clouds throw some other exception or doesn't support - # discovery. In that case try to determine version from auth_url - # API version from the original URL - url_parts = urlparse.urlparse(auth_url) - (scheme, netloc, path, params, query, fragment) = url_parts - path = path.lower() - if path.startswith('/v3'): - return v3_ksclient.Client(**kwargs) - elif path.startswith('/v2'): - return v2_ksclient.Client(**kwargs) diff --git a/designateclient/v1/__init__.py b/designateclient/v1/__init__.py index b7acd82..a30150a 100644 --- a/designateclient/v1/__init__.py +++ b/designateclient/v1/__init__.py @@ -13,11 +13,13 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -import requests +from keystoneclient import adapter +from keystoneclient.auth.identity import generic +from keystoneclient import session as ks_session from stevedore import extension from designateclient import exceptions -from designateclient import utils +from designateclient import version class Client(object): @@ -30,51 +32,62 @@ class Client(object): project_id=None, project_domain_name=None, project_domain_id=None, auth_url=None, token=None, endpoint_type=None, region_name=None, service_type=None, - insecure=False): + insecure=False, verify=None, session=None, auth=None): """ :param endpoint: Endpoint URL :param token: A token instead of username / password :param insecure: Allow "insecure" HTTPS requests """ - if not endpoint or not token: - ksclient = utils.get_ksclient( - username=username, user_id=user_id, - user_domain_id=user_domain_id, - user_domain_name=user_domain_name, password=password, - tenant_id=tenant_id, tenant_name=tenant_name, - project_id=project_id, project_name=project_name, - project_domain_id=project_domain_id, - project_domain_name=project_domain_name, - auth_url=auth_url, - token=token, - insecure=insecure) - ksclient.authenticate() + # Backwards compat to preserve the functionality of insecure. + if verify is None and insecure: + verify = False + else: + verify = True - token = token or ksclient.auth_token + # Compatibility code to mimic the old behaviour of the client + if session is None: + session = ks_session.Session(verify=verify) - filters = { - 'region_name': region_name, - 'service_type': service_type, - 'endpoint_type': endpoint_type, + auth_args = { + 'auth_url': auth_url, + 'domain_id': domain_id, + 'domain_name': domain_name, + 'project_id': project_id, + 'project_name': project_name, + 'project_domain_name': project_domain_name, + 'project_domain_id': project_domain_id, + 'tenant_id': tenant_id, + 'tenant_name': tenant_name, } - endpoint = endpoint or self._get_endpoint(ksclient, **filters) - self.endpoint = endpoint.rstrip('/') + if token: + auth_args['token'] = token + session.auth = generic.Token(**auth_args) + else: + password_args = { + 'username': username, + 'user_id': user_id, + 'user_domain_id': user_domain_id, + 'user_domain_name': user_domain_name, + 'password': password + } + auth_args.update(password_args) + session.auth = generic.Password(**auth_args) - # NOTE(kiall): As we're in the Version 1 client, we ensure we're - # pointing at the version 1 API. - if not self.endpoint.endswith('v1'): - self.endpoint = "%s/v1" % self.endpoint + # Since we have to behave nicely like a legacy client/bindings we use + # an adapter around the session to not modify it's state. + interface = endpoint_type.rstrip('URL') - self.insecure = insecure - - headers = {'Content-Type': 'application/json'} - - if token is not None: - headers['X-Auth-Token'] = token - - self.requests = requests.Session() - self.requests.headers.update(headers) + self.session = adapter.Adapter( + session, + auth=auth, + endpoint_override=endpoint, + region_name=region_name, + service_type=service_type, + interface=interface, + user_agent='python-designateclient-%s' % version.version_info, + version='1' + ) def _load_controller(ext): controller = ext.plugin(client=self) @@ -90,12 +103,9 @@ class Client(object): :param func: The function to wrap """ - # Prepend the endpoint URI - args = list(args) - args[0] = '%s/%s' % (self.endpoint, args[0]) - - if self.insecure is True: - kw['verify'] = False + kw['raise_exc'] = False + kw.setdefault('headers', {}) + kw['headers'].setdefault('Content-Type', 'application/json') # Trigger the request response = func(*args, **kw) @@ -119,26 +129,14 @@ class Client(object): else: return response - def _get_endpoint(self, client, **kwargs): - """Get an endpoint using the provided keystone client.""" - if kwargs.get('region_name'): - return client.service_catalog.url_for( - service_type=kwargs.get('service_type') or 'dns', - attr='region', - filter_value=kwargs.get('region_name'), - endpoint_type=kwargs.get('endpoint_type') or 'publicURL') - return client.service_catalog.url_for( - service_type=kwargs.get('service_type') or 'dns', - endpoint_type=kwargs.get('endpoint_type') or 'publicURL') - def get(self, path, **kw): - return self.wrap_api_call(self.requests.get, path, **kw) + return self.wrap_api_call(self.session.get, path, **kw) def post(self, path, **kw): - return self.wrap_api_call(self.requests.post, path, **kw) + return self.wrap_api_call(self.session.post, path, **kw) def put(self, path, **kw): - return self.wrap_api_call(self.requests.put, path, **kw) + return self.wrap_api_call(self.session.put, path, **kw) def delete(self, path, **kw): - return self.wrap_api_call(self.requests.delete, path, **kw) + return self.wrap_api_call(self.session.delete, path, **kw)