From be753eacbbcdd0bcb2d80c71c77ca6b99341b4d4 Mon Sep 17 00:00:00 2001 From: Monty Taylor Date: Mon, 18 Feb 2019 15:04:06 +0000 Subject: [PATCH] Bail earlier on a version mismatch for a supported service When we can't find a version for a service we do know about, the behavior of falling through to an empty Proxy just leads to massive end-user confusion. Throw an error. Change-Id: I7625a2b076fcebe2d66c412503fe3e7681f26918 --- openstack/service_description.py | 10 +++- .../unit/fixtures/bad-glance-version.json | 15 ++++++ .../unit/fixtures/catalog-bogus-glance.json | 52 +++++++++++++++++++ openstack/tests/unit/test_missing_version.py | 40 ++++++++++++++ ...il-on-failed-service-cf299c37d5647b08.yaml | 6 +++ 5 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 openstack/tests/unit/fixtures/bad-glance-version.json create mode 100644 openstack/tests/unit/fixtures/catalog-bogus-glance.json create mode 100644 openstack/tests/unit/test_missing_version.py create mode 100644 releasenotes/notes/bail-on-failed-service-cf299c37d5647b08.yaml diff --git a/openstack/service_description.py b/openstack/service_description.py index bfe46a7f5..92446be18 100644 --- a/openstack/service_description.py +++ b/openstack/service_description.py @@ -177,7 +177,15 @@ class ServiceDescription(object): **version_kwargs ) found_version = temp_adapter.get_api_major_version() - if found_version is None: + if found_version is None and version_kwargs: + raise exceptions.NotSupported( + "The {service_type} service for {cloud}:{region_name}" + " exists but does not have any supported versions.".format( + service_type=self.service_type, + cloud=instance.name, + region_name=instance.config.region_name)) + proxy_class = self.supported_versions.get(str(found_version[0])) + if not proxy_class: # Maybe openstacksdk is being used for the passthrough # REST API proxy layer for an unknown service in the # service catalog that also doesn't have any useful diff --git a/openstack/tests/unit/fixtures/bad-glance-version.json b/openstack/tests/unit/fixtures/bad-glance-version.json new file mode 100644 index 000000000..0fd91011f --- /dev/null +++ b/openstack/tests/unit/fixtures/bad-glance-version.json @@ -0,0 +1,15 @@ +{ + "versions": [ + { + "status": "CURRENT", + "updated": "2013-07-23T11:33:21Z", + "links": [ + { + "href": "https://example.com/image/v7/", + "rel": "self" + } + ], + "id": "v7" + } + ] +} diff --git a/openstack/tests/unit/fixtures/catalog-bogus-glance.json b/openstack/tests/unit/fixtures/catalog-bogus-glance.json new file mode 100644 index 000000000..3a47d3f9e --- /dev/null +++ b/openstack/tests/unit/fixtures/catalog-bogus-glance.json @@ -0,0 +1,52 @@ +{ + "token": { + "audit_ids": [ + "Rvn7eHkiSeOwucBIPaKdYA" + ], + "catalog": [ + { + "endpoints": [ + { + "id": "32466f357f3545248c47471ca51b0d3a", + "interface": "public", + "region": "RegionOne", + "url": "https://example.com/image/" + } + ], + "name": "glance", + "type": "image" + } + ], + "expires_at": "9999-12-31T23:59:59Z", + "issued_at": "2016-12-17T14:25:05.000000Z", + "methods": [ + "password" + ], + "project": { + "domain": { + "id": "default", + "name": "default" + }, + "id": "1c36b64c840a42cd9e9b931a369337f0", + "name": "Default Project" + }, + "roles": [ + { + "id": "9fe2ff9ee4384b1894a90878d3e92bab", + "name": "_member_" + }, + { + "id": "37071fc082e14c2284c32a2761f71c63", + "name": "swiftoperator" + } + ], + "user": { + "domain": { + "id": "default", + "name": "default" + }, + "id": "c17534835f8f42bf98fc367e0bf35e09", + "name": "mordred" + } + } +} diff --git a/openstack/tests/unit/test_missing_version.py b/openstack/tests/unit/test_missing_version.py new file mode 100644 index 000000000..b1cdaa44e --- /dev/null +++ b/openstack/tests/unit/test_missing_version.py @@ -0,0 +1,40 @@ +# 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 testtools + +from openstack import exceptions +from openstack import proxy +from openstack.tests.unit import base + + +class TestMissingVersion(base.TestCase): + + def setUp(self): + super(TestMissingVersion, self).setUp() + self.use_keystone_v3(catalog='catalog-bogus-glance.json') + self.use_glance( + image_version_json='bad-glance-version.json', + image_discovery_url='https://example.com/image/') + + def test_unsupported_version(self): + + with testtools.ExpectedException(exceptions.NotSupported): + self.cloud.image.get('/') + + self.assert_calls() + + def test_unsupported_version_override(self): + self.cloud.config.config['image_api_version'] = '7' + self.assertTrue(isinstance(self.cloud.image, proxy.Proxy)) + + self.assert_calls() diff --git a/releasenotes/notes/bail-on-failed-service-cf299c37d5647b08.yaml b/releasenotes/notes/bail-on-failed-service-cf299c37d5647b08.yaml new file mode 100644 index 000000000..5f004f8cf --- /dev/null +++ b/releasenotes/notes/bail-on-failed-service-cf299c37d5647b08.yaml @@ -0,0 +1,6 @@ +--- +upgrade: + - | + When a known service cannot be resolved to a supported version, + an exception is now thrown instead of just returning a blank + Proxy object. This allows returning sane errors to users.