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
This commit is contained in:
Endre Karlson 2014-09-04 17:14:12 +02:00
parent 1cd0548802
commit 5b81006c54
2 changed files with 56 additions and 105 deletions

View File

@ -18,12 +18,7 @@ import json
import os 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 pkg_resources
import six.moves.urllib.parse as urlparse
from designateclient import exceptions from designateclient import exceptions
@ -97,45 +92,3 @@ def get_columns(data):
map(lambda item: map(_seen, item.keys()), data) map(lambda item: map(_seen, item.keys()), data)
return list(columns) 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)

View File

@ -13,11 +13,13 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # 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 stevedore import extension
from designateclient import exceptions from designateclient import exceptions
from designateclient import utils from designateclient import version
class Client(object): class Client(object):
@ -30,51 +32,62 @@ class Client(object):
project_id=None, project_domain_name=None, project_id=None, project_domain_name=None,
project_domain_id=None, auth_url=None, token=None, project_domain_id=None, auth_url=None, token=None,
endpoint_type=None, region_name=None, service_type=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 endpoint: Endpoint URL
:param token: A token instead of username / password :param token: A token instead of username / password
:param insecure: Allow "insecure" HTTPS requests :param insecure: Allow "insecure" HTTPS requests
""" """
if not endpoint or not token: # Backwards compat to preserve the functionality of insecure.
ksclient = utils.get_ksclient( if verify is None and insecure:
username=username, user_id=user_id, verify = False
user_domain_id=user_domain_id, else:
user_domain_name=user_domain_name, password=password, verify = True
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()
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 = { auth_args = {
'region_name': region_name, 'auth_url': auth_url,
'service_type': service_type, 'domain_id': domain_id,
'endpoint_type': endpoint_type, '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 # Since we have to behave nicely like a legacy client/bindings we use
# pointing at the version 1 API. # an adapter around the session to not modify it's state.
if not self.endpoint.endswith('v1'): interface = endpoint_type.rstrip('URL')
self.endpoint = "%s/v1" % self.endpoint
self.insecure = insecure self.session = adapter.Adapter(
session,
headers = {'Content-Type': 'application/json'} auth=auth,
endpoint_override=endpoint,
if token is not None: region_name=region_name,
headers['X-Auth-Token'] = token service_type=service_type,
interface=interface,
self.requests = requests.Session() user_agent='python-designateclient-%s' % version.version_info,
self.requests.headers.update(headers) version='1'
)
def _load_controller(ext): def _load_controller(ext):
controller = ext.plugin(client=self) controller = ext.plugin(client=self)
@ -90,12 +103,9 @@ class Client(object):
:param func: The function to wrap :param func: The function to wrap
""" """
# Prepend the endpoint URI kw['raise_exc'] = False
args = list(args) kw.setdefault('headers', {})
args[0] = '%s/%s' % (self.endpoint, args[0]) kw['headers'].setdefault('Content-Type', 'application/json')
if self.insecure is True:
kw['verify'] = False
# Trigger the request # Trigger the request
response = func(*args, **kw) response = func(*args, **kw)
@ -119,26 +129,14 @@ class Client(object):
else: else:
return response 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): 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): 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): 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): 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)