Allow to use oslo.config without global CONF
If an application doesn't use a global configuration object and load the middleware with api paste, they are no ways to read the configuration options from the application configuration file. This change fixes that, the api paste config will looks like: [filter:authtoken] paste.filter_factory = keystonemiddleware.auth_token:filter_factory oslo_config_project = aodh With this, the keystonemiddleware will automatically load the configuration of the project aodh with a local oslo.config object instead of the global one. This allows application to not rely of the global oslo.config object and continue to use paste and keystonemiddleware. Closes-bug: #1482078 Related-bug: #1406218 Change-Id: I48c3d6a6a5486c9c035a15a75c025be7f5abaab4
This commit is contained in:
parent
e7e5971139
commit
ba68a74e65
@ -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
|
||||
---------------------
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user