diff --git a/doc/source/middlewarearchitecture.rst b/doc/source/middlewarearchitecture.rst index ce760ef3..8d84d083 100644 --- a/doc/source/middlewarearchitecture.rst +++ b/doc/source/middlewarearchitecture.rst @@ -271,6 +271,20 @@ and set in ``nova.conf``: Note that middleware parameters in paste config take priority, they must be removed to use values in [keystone_authtoken] section. +If the service doesn't use the global oslo.config object (CONF), then the +olso config project name can be set it in paste config and +keystonemiddleware will load the project configuration itself. +Optionally the location of the configuration file can be set if oslo.config +is not able to discover it. + +.. code-block:: ini + + [filter:authtoken] + paste.filter_factory = keystonemiddleware.auth_token:filter_factory + oslo_config_project = nova + # oslo_config_file = /not_discoverable_location/nova.conf + + Configuration Options --------------------- diff --git a/keystonemiddleware/auth_token/__init__.py b/keystonemiddleware/auth_token/__init__.py index 930e8476..942567c7 100644 --- a/keystonemiddleware/auth_token/__init__.py +++ b/keystonemiddleware/auth_token/__init__.py @@ -622,6 +622,27 @@ class AuthProtocol(_BaseAuthProtocol): # conf value into correct type. self._conf = _conf_values_type_convert(conf) + # NOTE(sileht): If we don't want to use oslo.config global object + # we can set the paste "oslo_config_project" and the middleware + # will load the configuration with a local oslo.config object. + self._local_oslo_config = None + if 'oslo_config_project' in conf: + if 'oslo_config_file' in conf: + default_config_files = [conf['oslo_config_file']] + else: + default_config_files = None + + self._local_oslo_config = cfg.ConfigOpts() + self._local_oslo_config( + {}, project=conf['oslo_config_project'], + default_config_files=default_config_files, + validate_default_values=True) + + self._local_oslo_config.register_opts( + _OPTS, group=_base.AUTHTOKEN_GROUP) + auth.register_conf_options(self._local_oslo_config, + group=_base.AUTHTOKEN_GROUP) + super(AuthProtocol, self).__init__( app, log=log, @@ -668,6 +689,8 @@ class AuthProtocol(_BaseAuthProtocol): # try config from paste-deploy first if name in self._conf: return self._conf[name] + elif self._local_oslo_config: + return self._local_oslo_config[group][name] else: return CONF[group][name] @@ -937,7 +960,8 @@ class AuthProtocol(_BaseAuthProtocol): plugin_kwargs['log'] = self.log plugin_opts = plugin_class.get_options() - CONF.register_opts(plugin_opts, group=group) + (self._local_oslo_config or CONF).register_opts(plugin_opts, + group=group) for opt in plugin_opts: val = self._conf_get(opt.dest, group=group) @@ -960,6 +984,9 @@ class AuthProtocol(_BaseAuthProtocol): try: return self._conf_get('project') except cfg.NoSuchOptError: + # Prefer local oslo config object + if self._local_oslo_config: + return self._local_oslo_config.project try: # CONF.project will exist only if the service uses # oslo.config. It will only be set when the project diff --git a/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py b/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py index 1de09b7c..d78dd852 100644 --- a/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py +++ b/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py @@ -32,6 +32,7 @@ import mock from oslo_config import cfg from oslo_serialization import jsonutils from oslo_utils import timeutils +from oslotest import createfile import six import testresources import testtools @@ -2470,5 +2471,35 @@ class TestAuthPluginUserAgentGeneration(BaseAuthTokenMiddlewareTest): self.assertEqual(expected_ua, sess.user_agent) +class TestAuthPluginLocalOsloConfig(BaseAuthTokenMiddlewareTest): + def test_project_in_local_oslo_configuration(self): + options = { + 'auth_plugin': 'password', + 'auth_uri': uuid.uuid4().hex, + 'password': uuid.uuid4().hex, + } + + content = ("[keystone_authtoken]\n" + "auth_plugin=%(auth_plugin)s\n" + "auth_uri=%(auth_uri)s\n" + "password=%(password)s\n" % options) + conf_file_fixture = self.useFixture( + createfile.CreateFileWithContent("my_app", content)) + conf = {'oslo_config_project': 'my_app', + 'oslo_config_file': conf_file_fixture.path} + app = self._create_app(conf, uuid.uuid4().hex) + for option in options: + self.assertEqual(options[option], app._conf_get(option)) + + def _create_app(self, conf, project_version): + fake_pkg_resources = mock.Mock() + fake_pkg_resources.get_distribution().version = project_version + + body = uuid.uuid4().hex + with mock.patch('keystonemiddleware.auth_token.pkg_resources', + new=fake_pkg_resources): + return self.create_simple_middleware(body=body, conf=conf) + + def load_tests(loader, tests, pattern): return testresources.OptimisingTestSuite(tests)