From f6037a3d50a80d8c2e0044c8f72d23dddb0d7203 Mon Sep 17 00:00:00 2001 From: Jens Harbott Date: Thu, 11 Apr 2019 14:02:00 +0000 Subject: [PATCH] Add a new option to choose the Identity endpoint Previously the admin Identity endpoint was hardcoded to be used. Now that keystone has dropped v2 support, deploying an admin Identity endpoint is no longer useful, so allow this to be changed by the deployer. Keep the default as using the `admin` endpoint, but create a deprecation message so that we can change the default in the future. Partial-Bug: 1830002 Change-Id: I993a45ccb1109d67e65bf32d1e134cc9bec2d88e --- doc/source/middlewarearchitecture.rst | 3 ++- keystonemiddleware/auth_token/__init__.py | 7 ++++--- keystonemiddleware/auth_token/_identity.py | 15 +++++++++++---- keystonemiddleware/auth_token/_opts.py | 6 +++++- keystonemiddleware/tests/unit/test_opts.py | 2 ++ .../notes/interface-option-ed551d2a3162668d.yaml | 9 +++++++++ 6 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 releasenotes/notes/interface-option-ed551d2a3162668d.yaml diff --git a/doc/source/middlewarearchitecture.rst b/doc/source/middlewarearchitecture.rst index bc1c5049..123b8417 100644 --- a/doc/source/middlewarearchitecture.rst +++ b/doc/source/middlewarearchitecture.rst @@ -174,11 +174,12 @@ when ``auth_plugin`` is set to ``password``. user_domain_name = Default username = nova password = ServicePassword + interface = public auth_url = http://127.0.0.1:5000 # Any of the options that could be set in api-paste.ini can be set here. If using an ``auth_plugin``, connection to the Identity service will be -established on the ``admin`` interface as registered in the service catalog. +established on the ``interface`` as registered in the service catalog. In the case where you are using an ``auth_plugin`` and have multiple regions, also specify the ``region_name`` option to fetch the correct endpoint. diff --git a/keystonemiddleware/auth_token/__init__.py b/keystonemiddleware/auth_token/__init__.py index 72ba2239..6041e9ea 100644 --- a/keystonemiddleware/auth_token/__init__.py +++ b/keystonemiddleware/auth_token/__init__.py @@ -251,7 +251,6 @@ _LOG = logging.getLogger(__name__) _CACHE_INVALID_INDICATOR = 'invalid' oslo_cache.configure(cfg.CONF) - AUTH_TOKEN_OPTS = [ (_base.AUTHTOKEN_GROUP, _opts._OPTS + _auth.OPTS + loading.get_auth_common_conf_options()) @@ -570,6 +569,7 @@ class AuthProtocol(BaseAuthProtocol): self._include_service_catalog = self._conf.get( 'include_service_catalog') self._hash_algorithms = self._conf.get('hash_algorithms') + self._interface = self._conf.get('interface') self._auth = self._create_auth_plugin() self._session = self._create_session() @@ -907,7 +907,7 @@ class AuthProtocol(BaseAuthProtocol): self._session, auth=self._auth, service_type='identity', - interface='admin', + interface=self._interface, region_name=self._conf.get('region_name'), connect_retries=self._conf.get('http_request_max_retries')) @@ -918,7 +918,8 @@ class AuthProtocol(BaseAuthProtocol): self.log, adap, include_service_catalog=self._include_service_catalog, - requested_auth_version=auth_version) + requested_auth_version=auth_version, + requested_auth_interface=self._interface) def _create_oslo_cache(self): # having this as a function makes test mocking easier diff --git a/keystonemiddleware/auth_token/_identity.py b/keystonemiddleware/auth_token/_identity.py index 36639a6b..aeeb8d94 100644 --- a/keystonemiddleware/auth_token/_identity.py +++ b/keystonemiddleware/auth_token/_identity.py @@ -41,8 +41,10 @@ class _RequestStrategy(object): AUTH_VERSION = None - def __init__(self, adap, include_service_catalog=None): + def __init__(self, adap, include_service_catalog=None, + requested_auth_interface=None): self._include_service_catalog = include_service_catalog + self._requested_auth_interface = requested_auth_interface def verify_token(self, user_token, allow_expired=False): pass @@ -93,7 +95,10 @@ class _V3RequestStrategy(_RequestStrategy): def __init__(self, adap, **kwargs): super(_V3RequestStrategy, self).__init__(adap, **kwargs) - self._client = v3_client.Client(session=adap) + client_args = {'session': adap} + if self._requested_auth_interface: + client_args['interface'] = self._requested_auth_interface + self._client = v3_client.Client(**client_args) def verify_token(self, token, allow_expired=False): auth_ref = self._client.tokens.validate( @@ -128,11 +133,12 @@ class IdentityServer(object): """ def __init__(self, log, adap, include_service_catalog=None, - requested_auth_version=None): + requested_auth_version=None, requested_auth_interface=None): self._LOG = log self._adapter = adap self._include_service_catalog = include_service_catalog self._requested_auth_version = requested_auth_version + self._requested_auth_interface = requested_auth_interface # Built on-demand with self._request_strategy. self._request_strategy_obj = None @@ -163,7 +169,8 @@ class IdentityServer(object): self._request_strategy_obj = strategy_class( self._adapter, - include_service_catalog=self._include_service_catalog) + include_service_catalog=self._include_service_catalog, + requested_auth_interface=self._requested_auth_interface) return self._request_strategy_obj diff --git a/keystonemiddleware/auth_token/_opts.py b/keystonemiddleware/auth_token/_opts.py index 941d0adb..6231b6db 100644 --- a/keystonemiddleware/auth_token/_opts.py +++ b/keystonemiddleware/auth_token/_opts.py @@ -66,7 +66,11 @@ _OPTS = [ ' favor of www_authenticate_uri and will be removed in the S' ' release.'), cfg.StrOpt('auth_version', - help='API version of the admin Identity API endpoint.'), + help='API version of the Identity API endpoint.'), + cfg.StrOpt('interface', + default='admin', + help='Interface to use for the Identity API endpoint. Valid' + ' values are "public", "internal" or "admin"(default).'), cfg.BoolOpt('delay_auth_decision', default=False, help='Do not handle authorization requests within the' diff --git a/keystonemiddleware/tests/unit/test_opts.py b/keystonemiddleware/tests/unit/test_opts.py index 3b4e510e..143264c9 100644 --- a/keystonemiddleware/tests/unit/test_opts.py +++ b/keystonemiddleware/tests/unit/test_opts.py @@ -33,6 +33,7 @@ class OptsTestCase(utils.TestCase): expected_opt_names = [ 'auth_admin_prefix', 'auth_host', + 'interface', 'auth_port', 'auth_protocol', 'www_authenticate_uri', @@ -86,6 +87,7 @@ class OptsTestCase(utils.TestCase): # This is the sample config generator list WITHOUT deprecations expected_opt_names = [ 'www_authenticate_uri', + 'interface', 'auth_uri', 'auth_version', 'delay_auth_decision', diff --git a/releasenotes/notes/interface-option-ed551d2a3162668d.yaml b/releasenotes/notes/interface-option-ed551d2a3162668d.yaml new file mode 100644 index 00000000..4771e869 --- /dev/null +++ b/releasenotes/notes/interface-option-ed551d2a3162668d.yaml @@ -0,0 +1,9 @@ +--- +features: + - | + [`bug 1830002 `_] + In order to allow an installation to work without deploying an admin + Identity endpoint, a new option `interface` has been added, allowing + select the Identity endpoint that is being used when verifying auth + tokens. It defaults to `admin` in order to replicate the old behaviour, + but may be set to `public` or `internal` as needed.