diff --git a/keystonemiddleware/_common/config.py b/keystonemiddleware/_common/config.py index 4e816a21..14480fe7 100644 --- a/keystonemiddleware/_common/config.py +++ b/keystonemiddleware/_common/config.py @@ -10,7 +10,10 @@ # License for the specific language governing permissions and limitations # under the License. +import pkg_resources + from oslo_config import cfg +import pbr import six from keystonemiddleware import exceptions @@ -63,7 +66,7 @@ def _conf_values_type_convert(group_name, all_options, conf): class Config(object): - def __init__(self, group_name, all_options, conf): + def __init__(self, name, group_name, all_options, conf): # 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. @@ -95,8 +98,10 @@ class Config(object): 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 @@ -130,3 +135,23 @@ class Config(object): 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 diff --git a/keystonemiddleware/auth_token/__init__.py b/keystonemiddleware/auth_token/__init__.py index 878f0449..42d5d155 100644 --- a/keystonemiddleware/auth_token/__init__.py +++ b/keystonemiddleware/auth_token/__init__.py @@ -219,7 +219,6 @@ from keystoneauth1.loading import session as session_loading from keystoneclient.common import cms from keystoneclient import exceptions as ksc_exceptions from oslo_serialization import jsonutils -import pkg_resources import six import webob.dec @@ -257,13 +256,6 @@ def _token_is_v3(token_info): return ('token' in token_info) -def _get_project_version(project): - try: - return pkg_resources.get_distribution(project).version - except pkg_resources.DistributionNotFound: - return "unknown" - - def _uncompress_pkiz(token): # TypeError If the signed_text is not zlib compressed binascii.Error if # signed_text has incorrect base64 padding (py34) @@ -470,7 +462,8 @@ class AuthProtocol(BaseAuthProtocol): log = logging.getLogger(conf.get('log_name', __name__)) log.info(_LI('Starting Keystone auth_token middleware')) - self._conf = config.Config(_base.AUTHTOKEN_GROUP, + self._conf = config.Config('auth_token', + _base.AUTHTOKEN_GROUP, opts.list_auth_token_opts(), conf) @@ -808,20 +801,6 @@ class AuthProtocol(BaseAuthProtocol): getter = lambda opt: self._conf.get(opt.dest, group=group) return plugin_loader.load_from_options_getter(getter) - def _build_useragent_string(self): - project = self._conf.project or '' - if project: - project_version = _get_project_version(project) - project = '{project}/{project_version} '.format( - project=project, - project_version=project_version) - - ua_template = ('{project}' - 'keystonemiddleware.auth_token/{ksm_version}') - return ua_template.format( - project=project, - ksm_version=_get_project_version('keystonemiddleware')) - def _create_identity_server(self): # NOTE(jamielennox): Loading Session here should be exactly the # same as calling Session.load_from_conf_options(CONF, GROUP) @@ -833,7 +812,7 @@ class AuthProtocol(BaseAuthProtocol): cacert=self._conf.get('cafile'), insecure=self._conf.get('insecure'), timeout=self._conf.get('http_connect_timeout'), - user_agent=self._build_useragent_string() + user_agent=self._conf.user_agent, ) auth_plugin = self._get_auth_plugin() 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 979dbe30..7c63032b 100644 --- a/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py +++ b/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py @@ -15,7 +15,6 @@ import datetime import logging import os -import pkg_resources import shutil import stat import tempfile @@ -33,6 +32,7 @@ import mock from oslo_config import cfg from oslo_serialization import jsonutils from oslo_utils import timeutils +import pbr.version import six import testresources import testtools @@ -2479,19 +2479,20 @@ class TestAuthPluginUserAgentGeneration(BaseAuthTokenMiddlewareTest): ksm_version = uuid.uuid4().hex conf = {'username': self.username, 'auth_url': self.auth_url} - app = self._create_app(conf, ksm_version) + app = self._create_app(conf, '', ksm_version) self._assert_user_agent(app, '', ksm_version) def test_project_in_configuration(self): project = uuid.uuid4().hex project_version = uuid.uuid4().hex + ksm_version = uuid.uuid4().hex conf = {'username': self.username, 'auth_url': self.auth_url, 'project': project} - app = self._create_app(conf, project_version) + app = self._create_app(conf, project_version, ksm_version) project_with_version = '{0}/{1} '.format(project, project_version) - self._assert_user_agent(app, project_with_version, project_version) + self._assert_user_agent(app, project_with_version, ksm_version) def test_project_not_installed_results_in_unknown_version(self): project = uuid.uuid4().hex @@ -2500,7 +2501,7 @@ class TestAuthPluginUserAgentGeneration(BaseAuthTokenMiddlewareTest): 'auth_url': self.auth_url, 'project': project} - v = pkg_resources.get_distribution('keystonemiddleware').version + v = pbr.version.VersionInfo('keystonemiddleware').version_string() app = self.create_simple_middleware(conf=conf, use_global_conf=True) project_with_version = '{0}/{1} '.format(project, 'unknown') @@ -2509,22 +2510,32 @@ class TestAuthPluginUserAgentGeneration(BaseAuthTokenMiddlewareTest): def test_project_in_oslo_configuration(self): project = uuid.uuid4().hex project_version = uuid.uuid4().hex + ksm_version = uuid.uuid4().hex conf = {'username': self.username, 'auth_url': self.auth_url} with mock.patch.object(cfg.CONF, 'project', new=project, create=True): - app = self._create_app(conf, project_version) + app = self._create_app(conf, project_version, ksm_version) project = '{0}/{1} '.format(project, project_version) - self._assert_user_agent(app, project, project_version) + self._assert_user_agent(app, project, ksm_version) - def _create_app(self, conf, project_version): + def _create_app(self, conf, project_version, ksm_version): fake_pkg_resources = mock.Mock() fake_pkg_resources.get_distribution().version = project_version + fake_version_info = mock.Mock() + fake_version_info.version_string.return_value = ksm_version + fake_pbr_version = mock.Mock() + fake_pbr_version.VersionInfo.return_value = fake_version_info + body = uuid.uuid4().hex - with mock.patch('keystonemiddleware.auth_token.pkg_resources', + + at_pbr = 'keystonemiddleware._common.config.pbr.version' + + with mock.patch('keystonemiddleware._common.config.pkg_resources', new=fake_pkg_resources): - return self.create_simple_middleware(body=body, conf=conf, - use_global_conf=True) + with mock.patch(at_pbr, new=fake_pbr_version): + return self.create_simple_middleware(body=body, conf=conf, + use_global_conf=True) def _assert_user_agent(self, app, project, ksm_version): sess = app._identity_server._adapter.session diff --git a/keystonemiddleware/tests/unit/auth_token/test_config.py b/keystonemiddleware/tests/unit/auth_token/test_config.py index 40e39535..2fccffa5 100644 --- a/keystonemiddleware/tests/unit/auth_token/test_config.py +++ b/keystonemiddleware/tests/unit/auth_token/test_config.py @@ -77,7 +77,7 @@ class TestAuthPluginLocalOsloConfig(base.BaseAuthTokenTestCase): fake_pkg_resources.get_distribution().version = project_version body = uuid.uuid4().hex - with mock.patch('keystonemiddleware.auth_token.pkg_resources', + with mock.patch('keystonemiddleware._common.config.pkg_resources', new=fake_pkg_resources): # use_global_conf is poorly named. What it means is # don't use the config created in test setUp.