From cebeb820068b3aa7f7a8a145888e226430987868 Mon Sep 17 00:00:00 2001 From: Dmitry Tantsur Date: Fri, 31 May 2019 15:05:48 +0200 Subject: [PATCH] Convert Swift connection errors into more obvious ones Currently we handle Swift errors on putting/getting objects, but not on connections. This patch improves it for better error messages. This also means that commit 09938a397595b92f19f6415bb3cfec8be76fe6a3 is incomplete and does not actually fix the extra-hardware plugin when Swift is absent. This change corrects it. Change-Id: I0e8e76291653dd2e0cd3cde35d18a1e8f9c91853 --- ironic_inspector/common/swift.py | 21 +++++++++++++++------ ironic_inspector/test/unit/test_swift.py | 20 +++++++++++++++++++- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/ironic_inspector/common/swift.py b/ironic_inspector/common/swift.py index a06e49dce..4ed7260e2 100644 --- a/ironic_inspector/common/swift.py +++ b/ironic_inspector/common/swift.py @@ -48,24 +48,33 @@ class SwiftAPI(object): Authentification is loaded from config file. """ global SWIFT_SESSION - if not SWIFT_SESSION: - SWIFT_SESSION = keystone.get_session('swift') adapter_opts = dict() # TODO(pas-ha): remove handling deprecated options in Rocky if CONF.swift.os_region and not CONF.swift.region_name: adapter_opts['region_name'] = CONF.swift.os_region - adapter = keystone.get_adapter('swift', session=SWIFT_SESSION, - **adapter_opts) + try: + if not SWIFT_SESSION: + SWIFT_SESSION = keystone.get_session('swift') + + adapter = keystone.get_adapter('swift', session=SWIFT_SESSION, + **adapter_opts) + except Exception as exc: + raise utils.Error(_("Could not create an adapter to connect to " + "the object storage service: %s") % exc) # TODO(pas-ha) reverse-construct SSL-related session options here params = { 'os_options': { 'object_storage_url': adapter.get_endpoint()}} - self.connection = swift_client.Connection(session=SWIFT_SESSION, - **params) + try: + self.connection = swift_client.Connection(session=SWIFT_SESSION, + **params) + except Exception as exc: + raise utils.Error(_("Could not connect to the object storage " + "service: %s") % exc) def create_object(self, object, data, container=CONF.swift.container, headers=None): diff --git a/ironic_inspector/test/unit/test_swift.py b/ironic_inspector/test/unit/test_swift.py index c32071c76..a8208f6c2 100644 --- a/ironic_inspector/test/unit/test_swift.py +++ b/ironic_inspector/test/unit/test_swift.py @@ -14,7 +14,7 @@ # Mostly copied from ironic/tests/test_swift.py - +from keystoneauth1 import exceptions as ks_exc from keystoneauth1 import loading as kloading import mock from swiftclient import client as swift_client @@ -76,6 +76,24 @@ class SwiftTestCase(BaseTest): session=load_mock.return_value, os_options={'object_storage_url': fake_endpoint}) + def test___init__keystone_failure(self, connection_mock, load_mock, + opts_mock, adapter_mock): + adapter_mock.side_effect = ks_exc.MissingRequiredOptions([]) + self.assertRaisesRegex(utils.Error, 'Could not create an adapter', + swift.SwiftAPI) + self.assertFalse(connection_mock.called) + + def test___init__swift_failure(self, connection_mock, load_mock, + opts_mock, adapter_mock): + fake_endpoint = "http://localhost:6000" + adapter_mock.return_value.get_endpoint.return_value = fake_endpoint + connection_mock.side_effect = RuntimeError() + self.assertRaisesRegex(utils.Error, 'Could not connect', + swift.SwiftAPI) + connection_mock.assert_called_once_with( + session=load_mock.return_value, + os_options={'object_storage_url': fake_endpoint}) + def test_create_object(self, connection_mock, load_mock, opts_mock, adapter_mock): swiftapi = swift.SwiftAPI()