160 lines
5.7 KiB
Python
160 lines
5.7 KiB
Python
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import pkg_resources
|
|
|
|
from oslo_config import cfg
|
|
from oslo_log import log as logging
|
|
import pbr
|
|
|
|
from keystonemiddleware import exceptions
|
|
from keystonemiddleware.i18n import _
|
|
|
|
CONF = cfg.CONF
|
|
_NOT_SET = object()
|
|
_LOG = logging.getLogger(__name__)
|
|
|
|
|
|
def _conf_values_type_convert(group_name, all_options, conf):
|
|
"""Convert conf values into correct type."""
|
|
if not conf:
|
|
return {}
|
|
|
|
opts = {}
|
|
opt_types = {}
|
|
|
|
for group, options in all_options:
|
|
# only accept paste overrides for the primary group
|
|
if group != group_name:
|
|
continue
|
|
|
|
for o in options:
|
|
type_dest = (getattr(o, 'type', str), o.dest)
|
|
opt_types[o.dest] = type_dest
|
|
# Also add the deprecated name with the same type and dest.
|
|
for d_o in o.deprecated_opts:
|
|
opt_types[d_o.name] = type_dest
|
|
|
|
break
|
|
|
|
for k, v in conf.items():
|
|
dest = k
|
|
try:
|
|
# 'here' and '__file__' come from paste.deploy
|
|
# 'configkey' is added by panko and gnocchi
|
|
if v is not None and k not in ['here', '__file__', 'configkey']:
|
|
type_, dest = opt_types[k]
|
|
v = type_(v)
|
|
except KeyError: # nosec
|
|
_LOG.warning(
|
|
'The option "%s" is not known to keystonemiddleware', k)
|
|
except ValueError as e:
|
|
raise exceptions.ConfigurationError(
|
|
_('Unable to convert the value of option "%(key)s" into '
|
|
'correct type: %(ex)s') % {'key': k, 'ex': e})
|
|
opts[dest] = v
|
|
|
|
return opts
|
|
|
|
|
|
class Config(object):
|
|
|
|
def __init__(self, name, group_name, all_options, conf):
|
|
local_oslo_config = conf.pop('oslo_config_config', None)
|
|
local_config_project = conf.pop('oslo_config_project', None)
|
|
local_config_file = conf.pop('oslo_config_file', None)
|
|
|
|
# NOTE(wanghong): If options are set in paste file, all the option
|
|
# values passed into conf are string type. So, we should convert the
|
|
# conf value into correct type.
|
|
self.paste_overrides = _conf_values_type_convert(group_name,
|
|
all_options,
|
|
conf)
|
|
|
|
# NOTE(sileht, cdent): If we don't want to use oslo.config global
|
|
# object there are two options: set "oslo_config_project" in
|
|
# paste.ini and the middleware will load the configuration with a
|
|
# local oslo.config object or the caller which instantiates
|
|
# AuthProtocol can pass in an existing oslo.config as the
|
|
# value of the "oslo_config_config" key in conf. If both are
|
|
# set "olso_config_config" is used.
|
|
if local_config_project and not local_oslo_config:
|
|
config_files = [local_config_file] if local_config_file else None
|
|
|
|
local_oslo_config = cfg.ConfigOpts()
|
|
local_oslo_config([],
|
|
project=local_config_project,
|
|
default_config_files=config_files,
|
|
validate_default_values=True)
|
|
|
|
if local_oslo_config:
|
|
for group, opts in all_options:
|
|
local_oslo_config.register_opts(opts, group=group)
|
|
|
|
self.name = name
|
|
self.oslo_conf_obj = local_oslo_config or cfg.CONF
|
|
self.group_name = group_name
|
|
self._user_agent = None
|
|
|
|
def get(self, name, group=_NOT_SET):
|
|
# try config from paste-deploy first
|
|
try:
|
|
return self.paste_overrides[name]
|
|
except KeyError:
|
|
if group is _NOT_SET:
|
|
group = self.group_name
|
|
|
|
return self.oslo_conf_obj[group][name]
|
|
|
|
@property
|
|
def project(self):
|
|
"""Determine a project name from all available config sources.
|
|
|
|
The sources are checked in the following order:
|
|
|
|
1. The paste-deploy config for auth_token middleware
|
|
2. The keystone_authtoken or base group in the project's config
|
|
3. The oslo.config CONF.project property
|
|
|
|
"""
|
|
try:
|
|
return self.get('project', group=self.group_name)
|
|
except cfg.NoSuchOptError:
|
|
try:
|
|
# CONF.project will exist only if the service uses
|
|
# oslo.config. It will only be set when the project
|
|
# calls CONF(...) and when not set oslo.config oddly
|
|
# raises a NoSuchOptError exception.
|
|
return self.oslo_conf_obj.project
|
|
except cfg.NoSuchOptError:
|
|
return None
|
|
|
|
@property
|
|
def user_agent(self):
|
|
if not self._user_agent:
|
|
project = self.project or ''
|
|
|
|
if project:
|
|
try:
|
|
version = pkg_resources.get_distribution(project).version
|
|
except pkg_resources.DistributionNotFound:
|
|
version = "unknown"
|
|
|
|
project = "%s/%s " % (project, version)
|
|
|
|
self._user_agent = "%skeystonemiddleware.%s/%s" % (
|
|
project,
|
|
self.name,
|
|
pbr.version.VersionInfo('keystonemiddleware').version_string())
|
|
|
|
return self._user_agent
|