summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamie Lennox <jamielennox@redhat.com>2014-08-28 11:57:06 +1000
committerJamie Lennox <jamielennox@redhat.com>2014-09-01 10:48:32 +1000
commit22a93fceb40fd289e5c5d91d1b1b10e40b0a0ae9 (patch)
tree4471f80658f036bbed108693eb313a69e19900e5
parent1643f7da32b1f729f12d042565d8c67f10f91b8c (diff)
downloadpython-keystoneclient-22a93fceb40fd289e5c5d91d1b1b10e40b0a0ae9.tar.gz
Allow providing an endpoint_override to requests
As much as I'd prefer not to need this functionality there are plenty of existing clients that we want to have use the adapter that can accept a bypass argument such that it ignores the service catalog and uses that URL for all requests. We therefore need to be able to support similar functionality in our adapter. Change-Id: I206705241ff9b84967d0d9c089b4795bcc26b65e
-rw-r--r--keystoneclient/adapter.py11
-rw-r--r--keystoneclient/session.py18
-rw-r--r--keystoneclient/tests/test_session.py58
3 files changed, 80 insertions, 7 deletions
diff --git a/keystoneclient/adapter.py b/keystoneclient/adapter.py
index 1018b02..605b1ec 100644
--- a/keystoneclient/adapter.py
+++ b/keystoneclient/adapter.py
@@ -26,8 +26,8 @@ class Adapter(object):
@utils.positional()
def __init__(self, session, service_type=None, service_name=None,
- interface=None, region_name=None, auth=None,
- user_agent=None):
+ interface=None, region_name=None, endpoint_override=None,
+ auth=None, user_agent=None):
"""Create a new adapter.
:param Session session: The session object to wrap.
@@ -35,16 +35,18 @@ class Adapter(object):
:param str service_name: The default service_name for URL discovery.
:param str interface: The default interface for URL discovery.
:param str region_name: The default region_name for URL discovery.
+ :param str endpoint_override: Always use this endpoint URL for requests
+ for this client.
:param auth.BaseAuthPlugin auth: An auth plugin to use instead of the
session one.
:param str user_agent: The User-Agent string to set.
"""
-
self.session = session
self.service_type = service_type
self.service_name = service_name
self.interface = interface
self.region_name = region_name
+ self.endpoint_override = endpoint_override
self.user_agent = user_agent
self.auth = auth
@@ -60,6 +62,9 @@ class Adapter(object):
if self.region_name:
endpoint_filter.setdefault('region_name', self.region_name)
+ if self.endpoint_override:
+ kwargs.setdefault('endpoint_override', self.endpoint_override)
+
if self.auth:
kwargs.setdefault('auth', self.auth)
if self.user_agent:
diff --git a/keystoneclient/session.py b/keystoneclient/session.py
index a923a64..d432cd4 100644
--- a/keystoneclient/session.py
+++ b/keystoneclient/session.py
@@ -183,7 +183,8 @@ class Session(object):
def request(self, url, method, json=None, original_ip=None,
user_agent=None, redirect=None, authenticated=None,
endpoint_filter=None, auth=None, requests_auth=None,
- raise_exc=True, allow_reauth=True, log=True, **kwargs):
+ raise_exc=True, allow_reauth=True, log=True,
+ endpoint_override=None, **kwargs):
"""Send an HTTP request with the specified characteristics.
Wrapper around `requests.Session.request` to handle tasks such as
@@ -218,6 +219,11 @@ class Session(object):
endpoint to use for this request. If not
provided then URL is expected to be a
fully qualified URL. (optional)
+ :param str endpoint_override: The URL to use instead of looking up the
+ endpoint in the auth plugin. This will be
+ ignored if a fully qualified URL is
+ provided but take priority over an
+ endpoint_filter. (optional)
:param auth: The auth plugin to use when authenticating this request.
This will override the plugin that is attached to the
session (if any). (optional)
@@ -266,9 +272,13 @@ class Session(object):
# should ignore the filter. This will make it easier for clients who
# want to overrule the default endpoint_filter data added to all client
# requests. We check fully qualified here by the presence of a host.
- url_data = urllib.parse.urlparse(url)
- if endpoint_filter and not url_data.netloc:
- base_url = self.get_endpoint(auth, **endpoint_filter)
+ if not urllib.parse.urlparse(url).netloc:
+ base_url = None
+
+ if endpoint_override:
+ base_url = endpoint_override
+ elif endpoint_filter:
+ base_url = self.get_endpoint(auth, **endpoint_filter)
if not base_url:
raise exceptions.EndpointNotFound()
diff --git a/keystoneclient/tests/test_session.py b/keystoneclient/tests/test_session.py
index 37477f6..c225ae1 100644
--- a/keystoneclient/tests/test_session.py
+++ b/keystoneclient/tests/test_session.py
@@ -499,6 +499,47 @@ class SessionAuthTests(utils.TestCase):
authenticated=True, allow_reauth=False)
self.assertFalse(auth.invalidate_called)
+ def test_endpoint_override_overrides_filter(self):
+ auth = CalledAuthPlugin()
+ sess = client_session.Session(auth=auth)
+
+ override_base = 'http://mytest/'
+ path = 'path'
+ override_url = override_base + path
+ resp_text = uuid.uuid4().hex
+
+ self.requests.register_uri('GET', override_url, text=resp_text)
+
+ resp = sess.get(path,
+ endpoint_override=override_base,
+ endpoint_filter={'service_type': 'identity'})
+
+ self.assertEqual(resp_text, resp.text)
+ self.assertEqual(override_url, self.requests.last_request.url)
+
+ self.assertTrue(auth.get_token_called)
+ self.assertFalse(auth.get_endpoint_called)
+
+ def test_endpoint_override_ignore_full_url(self):
+ auth = CalledAuthPlugin()
+ sess = client_session.Session(auth=auth)
+
+ path = 'path'
+ url = self.TEST_URL + path
+
+ resp_text = uuid.uuid4().hex
+ self.requests.register_uri('GET', url, text=resp_text)
+
+ resp = sess.get(url,
+ endpoint_override='http://someother.url',
+ endpoint_filter={'service_type': 'identity'})
+
+ self.assertEqual(resp_text, resp.text)
+ self.assertEqual(url, self.requests.last_request.url)
+
+ self.assertTrue(auth.get_token_called)
+ self.assertFalse(auth.get_endpoint_called)
+
class AdapterTest(utils.TestCase):
@@ -585,6 +626,23 @@ class AdapterTest(utils.TestCase):
getattr(adpt, method)(url)
m.assert_called_once_with(url, method.upper())
+ def test_setting_endpoint_override(self):
+ endpoint_override = 'http://overrideurl'
+ path = '/path'
+ endpoint_url = endpoint_override + path
+
+ auth = CalledAuthPlugin()
+ sess = client_session.Session(auth=auth)
+ adpt = adapter.Adapter(sess, endpoint_override=endpoint_override)
+
+ response = uuid.uuid4().hex
+ self.requests.register_uri('GET', endpoint_url, text=response)
+
+ resp = adpt.get(path)
+
+ self.assertEqual(response, resp.text)
+ self.assertEqual(endpoint_url, self.requests.last_request.url)
+
class ConfLoadingTests(utils.TestCase):