From f484736b7d087115b8330ae794c101f7f8e7b926 Mon Sep 17 00:00:00 2001 From: Jordan Pittier Date: Thu, 6 Oct 2016 16:00:46 +0200 Subject: cloud_config:get_session_endpoint: catch Keystone EndpointNotFound The docstring of the `get_session_endpoint` says ":returns: Endpoint for the service, or None if not found" but apparently the `None` part was forgotten. This leads to this kind of spectacular traceback where the exception bubles up (even through Shade): Traceback (most recent call last): File ".tox/run/bin/ospurge", line 11, in load_entry_point('ospurge', 'console_scripts', 'ospurge')() File "/path/ospurge/main.py", line 154, in main for resource in resource_manager.list(): File "/path/ospurge/resources/swift.py", line 15, in list for container in self.cloud.list_containers(): File "/path/pkg/shade/openstackcloud.py", line 4909, in list_containers full_listing=full_listing)) File "/path/pkg/shade/task_manager.py", line 244, in submit_task return task.wait(raw) File "/path/pkg/shade/task_manager.py", line 121, in wait super(Task, self).wait() File "/path/pkg/shade/task_manager.py", line 96, in wait self._traceback) File "/path/pkg/six.py", line 686, in reraise raise value File "/path/pkg/shade/task_manager.py", line 105, in run self.done(self.main(client)) File "/path/pkg/shade/_tasks.py", line 549, in main return client.swift_client.get_account(**self.args)[1] File "/path/pkg/shade/openstackcloud.py", line 849, in swift_client 'object-store', swiftclient.client.Connection) File "/path/pkg/shade/openstackcloud.py", line 343, in _get_client **kwargs) File "/path/pkg/os_client_config/cloud_config.py", line 301, in get_legacy_client return self._get_swift_client(client_class=client_class, **kwargs) File "/path/pkg/os_client_config/cloud_config.py", line 369, in _get_swift_client endpoint = self.get_session_endpoint(service_key='object-store') File "/path/pkg/os_client_config/cloud_config.py", line 253, in get_session_endpoint region_name=self.region) File "/path/pkg/keystoneauth1/session.py", line 765, in get_endpoint return auth.get_endpoint(self, **kwargs) File "/path/pkg/keystoneauth1/identity/base.py", line 216, in get_endpoint service_name=service_name) File "/path/pkg/positional/__init__.py", line 101, in inner return wrapped(*args, **kwargs) File "/path/pkg/keystoneauth1/access/service_catalog.py", line 228, in url_for raise exceptions.EndpointNotFound(msg) keystoneauth1.exceptions.catalog.EndpointNotFound: public endpoint for object-store service in RegionOne region not found Change-Id: Idbf5081117bb0a13d04a1a5cb9fd7682baaf04e5 --- os_client_config/cloud_config.py | 18 +++++++++++++----- os_client_config/tests/test_cloud_config.py | 9 +++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/os_client_config/cloud_config.py b/os_client_config/cloud_config.py index ae5da3a..a911d81 100644 --- a/os_client_config/cloud_config.py +++ b/os_client_config/cloud_config.py @@ -16,6 +16,7 @@ import importlib import warnings from keystoneauth1 import adapter +import keystoneauth1.exceptions.catalog from keystoneauth1 import plugin from keystoneauth1 import session import requestsexceptions @@ -247,11 +248,18 @@ class CloudConfig(object): if service_key == 'identity': endpoint = session.get_endpoint(interface=plugin.AUTH_INTERFACE) else: - endpoint = session.get_endpoint( - service_type=self.get_service_type(service_key), - service_name=self.get_service_name(service_key), - interface=self.get_interface(service_key), - region_name=self.region) + args = { + 'service_type': self.get_service_type(service_key), + 'service_name': self.get_service_name(service_key), + 'interface': self.get_interface(service_key), + 'region_name': self.region + } + try: + endpoint = session.get_endpoint(**args) + except keystoneauth1.exceptions.catalog.EndpointNotFound: + self.log.warning("Keystone catalog entry not found (%s)", + args) + endpoint = None return endpoint def get_legacy_client( diff --git a/os_client_config/tests/test_cloud_config.py b/os_client_config/tests/test_cloud_config.py index 7a8b77a..2763f4d 100644 --- a/os_client_config/tests/test_cloud_config.py +++ b/os_client_config/tests/test_cloud_config.py @@ -12,6 +12,7 @@ import copy +from keystoneauth1 import exceptions as ksa_exceptions from keystoneauth1 import plugin as ksa_plugin from keystoneauth1 import session as ksa_session import mock @@ -235,6 +236,14 @@ class TestCloudConfig(base.TestCase): region_name='region-al', service_type='orchestration') + @mock.patch.object(cloud_config.CloudConfig, 'get_session') + def test_session_endpoint_not_found(self, mock_get_session): + exc_to_raise = ksa_exceptions.catalog.EndpointNotFound + mock_get_session.return_value.get_endpoint.side_effect = exc_to_raise + cc = cloud_config.CloudConfig( + "test1", "region-al", {}, auth_plugin=mock.Mock()) + self.assertIsNone(cc.get_session_endpoint('notfound')) + @mock.patch.object(cloud_config.CloudConfig, 'get_api_version') @mock.patch.object(cloud_config.CloudConfig, 'get_auth_args') @mock.patch.object(cloud_config.CloudConfig, 'get_session_endpoint') -- cgit v1.2.1