From 83bef7473ddf39b68c09ae074c741652fc52185d Mon Sep 17 00:00:00 2001 From: Jamie Lennox Date: Fri, 4 Jul 2014 10:41:35 +1000 Subject: [PATCH] Add the 'auth' interface type There are certain requests that will always want to be sent to the auth_url. Add a new interface type to the get_endpoint command of the base identity plugin such that if you ask for the 'auth' interface it will give you the auth_url. Implements: blueprint session-auth-endpoint Change-Id: If653970354b919fdd6e80c061611c3aad129c574 --- keystoneclient/auth/__init__.py | 1 + keystoneclient/auth/base.py | 5 +++++ keystoneclient/auth/identity/base.py | 13 +++++++++++-- keystoneclient/httpclient.py | 2 +- keystoneclient/tests/auth/test_identity_common.py | 10 ++++++++++ 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/keystoneclient/auth/__init__.py b/keystoneclient/auth/__init__.py index c0c354999..932420722 100644 --- a/keystoneclient/auth/__init__.py +++ b/keystoneclient/auth/__init__.py @@ -18,6 +18,7 @@ from keystoneclient.auth.conf import * # noqa __all__ = [ # auth.base + 'AUTH_INTERFACE', 'BaseAuthPlugin', 'get_plugin_class', 'PLUGIN_NAMESPACE', diff --git a/keystoneclient/auth/base.py b/keystoneclient/auth/base.py index e9d4eed73..4a43c4cc3 100644 --- a/keystoneclient/auth/base.py +++ b/keystoneclient/auth/base.py @@ -17,6 +17,11 @@ import stevedore from keystoneclient import exceptions +# NOTE(jamielennox): The AUTH_INTERFACE is a special value that can be +# requested from get_endpoint. If a plugin receives this as the value of +# 'interface' it should return the initial URL that was passed to the plugin. +AUTH_INTERFACE = object() + PLUGIN_NAMESPACE = 'keystoneclient.auth.plugin' diff --git a/keystoneclient/auth/identity/base.py b/keystoneclient/auth/identity/base.py index 09af1fae8..fb5ed7a0d 100644 --- a/keystoneclient/auth/identity/base.py +++ b/keystoneclient/auth/identity/base.py @@ -125,8 +125,10 @@ class BaseIdentityPlugin(base.BaseAuthPlugin): for. This plugin will return None (failure) if service_type is not provided. :param string interface: The exposure of the endpoint. Should be - `public`, `internal` or `admin`. - Defaults to `public`. + `public`, `internal`, `admin`, or `auth`. + `auth` is special here to use the `auth_url` + rather than a URL extracted from the service + catalog. Defaults to `public`. :param string region_name: The region the endpoint should exist in. (optional) :param string service_name: The name of the service in the catalog. @@ -138,6 +140,13 @@ class BaseIdentityPlugin(base.BaseAuthPlugin): :return string or None: A valid endpoint URL or None if not available. """ + # NOTE(jamielennox): if you specifically ask for requests to be sent to + # the auth url then we can ignore the rest of the checks. Typically if + # you are asking for the auth endpoint it means that there is no + # catalog to query anyway. + if interface is base.AUTH_INTERFACE: + return self.auth_url + if not service_type: LOG.warn('Plugin cannot return an endpoint without knowing the ' 'service type that is required. Add service_type to ' diff --git a/keystoneclient/httpclient.py b/keystoneclient/httpclient.py index 48e12b7cf..d9fe955d6 100644 --- a/keystoneclient/httpclient.py +++ b/keystoneclient/httpclient.py @@ -268,7 +268,7 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin): return self.auth_token_from_user def get_endpoint(self, session, interface=None, **kwargs): - if interface == 'public': + if interface == 'public' or interface is base.AUTH_INTERFACE: return self.auth_url else: return self.management_url diff --git a/keystoneclient/tests/auth/test_identity_common.py b/keystoneclient/tests/auth/test_identity_common.py index da687f9cb..6557a8061 100644 --- a/keystoneclient/tests/auth/test_identity_common.py +++ b/keystoneclient/tests/auth/test_identity_common.py @@ -16,6 +16,7 @@ import uuid import httpretty import six +from keystoneclient.auth import base from keystoneclient.auth.identity import v2 from keystoneclient.auth.identity import v3 from keystoneclient.openstack.common import jsonutils @@ -208,6 +209,15 @@ class CommonIdentityTests(object): self.assertEqual(200, resp.status_code) self.assertEqual(body, resp.text) + def test_asking_for_auth_endpoint_ignores_checks(self): + a = self.create_auth_plugin() + s = session.Session(auth=a) + + auth_url = s.get_endpoint(service_type='compute', + interface=base.AUTH_INTERFACE) + + self.assertEqual(self.TEST_URL, auth_url) + class V3(CommonIdentityTests, utils.TestCase):