From 981a19bba1d5a8477d51ed4751c87a3a4d130aee Mon Sep 17 00:00:00 2001 From: Dmitry Tantsur Date: Mon, 27 Jul 2020 18:58:44 +0200 Subject: [PATCH] Correct major version discovery for non-keystone plugins When a non-keystone plugin is used together with an unversioned endpoint, we give up on discovery before figuring out both major version and the correct endpoint. This is because get_endpoint_data is called with discover_versions=False, so discovery assumes we have all information already. It may be an issue in discovery itself, but I'm afraid to touch that code. Instead, if get_endpoint_data returns no API version with discover_versions=False, try with discover_versions=True, which matches what the identity plugins do. Also increase the unit test coverage. Change-Id: Ie623931b150748d7759cf276e0023a2f06a8d4db --- keystoneauth1/plugin.py | 12 ++- keystoneauth1/tests/unit/test_discovery.py | 83 ++++++++++++++----- .../noauth-discovery-c26d82a32c36d41d.yaml | 5 ++ 3 files changed, 79 insertions(+), 21 deletions(-) create mode 100644 releasenotes/notes/noauth-discovery-c26d82a32c36d41d.yaml diff --git a/keystoneauth1/plugin.py b/keystoneauth1/plugin.py index 31719918..0fc3e011 100644 --- a/keystoneauth1/plugin.py +++ b/keystoneauth1/plugin.py @@ -149,8 +149,18 @@ class BaseAuthPlugin(object): endpoint_data = self.get_endpoint_data( session, endpoint_override=endpoint_override, discover_versions=False, **kwargs) - if endpoint_data: + if endpoint_data is None: + return + + if endpoint_data.api_version is None: + # No version detected from the URL, trying full discovery. + endpoint_data = self.get_endpoint_data( + session, endpoint_override=endpoint_override, + discover_versions=True, **kwargs) + + if endpoint_data and endpoint_data.api_version: return endpoint_data.api_version + return None def get_endpoint(self, session, **kwargs): diff --git a/keystoneauth1/tests/unit/test_discovery.py b/keystoneauth1/tests/unit/test_discovery.py index c8468923..75c72e44 100644 --- a/keystoneauth1/tests/unit/test_discovery.py +++ b/keystoneauth1/tests/unit/test_discovery.py @@ -748,37 +748,69 @@ class VersionDataTests(utils.TestCase): def test_endpoint_data_noauth_discover(self): mock = self.requests_mock.get( + BASE_URL, status_code=200, json=V3_VERSION_LIST) + self.requests_mock.get( V3_URL, status_code=200, json=V3_VERSION_ENTRY) - plugin = noauth.NoAuth() - data = plugin.get_endpoint_data(self.session, endpoint_override=V3_URL) + + plugin = noauth.NoAuth(endpoint=BASE_URL) + data = plugin.get_endpoint_data(self.session) self.assertEqual(data.api_version, (3, 0)) self.assertEqual(data.url, V3_URL) - self.assertEqual( - plugin.get_api_major_version( - self.session, endpoint_override=V3_URL), - (3, 0)) - self.assertEqual( - plugin.get_endpoint(self.session, endpoint_override=V3_URL), - V3_URL) + self.assertEqual(plugin.get_api_major_version(self.session), (3, 0)) + self.assertEqual(plugin.get_endpoint(self.session), BASE_URL) self.assertTrue(mock.called_once) + def test_endpoint_data_noauth_versioned_discover(self): + self.requests_mock.get( + BASE_URL, status_code=200, json=V3_VERSION_LIST) + self.requests_mock.get( + V3_URL, status_code=200, json=V3_VERSION_ENTRY) + + plugin = noauth.NoAuth(endpoint=V3_URL) + data = plugin.get_endpoint_data(self.session) + + self.assertEqual(data.api_version, (3, 0)) + self.assertEqual(data.url, V3_URL) + self.assertEqual(plugin.get_api_major_version(self.session), (3, 0)) + self.assertEqual(plugin.get_endpoint(self.session), V3_URL) + def test_endpoint_data_noauth_no_discover(self): + plugin = noauth.NoAuth(endpoint=V3_URL) + data = plugin.get_endpoint_data( + self.session, discover_versions=False) + + self.assertEqual(data.api_version, (3, 0)) + self.assertEqual(data.url, V3_URL) + self.assertEqual(plugin.get_api_major_version(self.session), (3, 0)) + self.assertEqual(plugin.get_endpoint(self.session), V3_URL) + + def test_endpoint_data_noauth_override_no_discover(self): plugin = noauth.NoAuth() data = plugin.get_endpoint_data( self.session, endpoint_override=V3_URL, discover_versions=False) self.assertEqual(data.api_version, (3, 0)) self.assertEqual(data.url, V3_URL) - self.assertEqual( - plugin.get_api_major_version( - self.session, endpoint_override=V3_URL), - (3, 0)) self.assertEqual( plugin.get_endpoint(self.session, endpoint_override=V3_URL), V3_URL) + def test_endpoint_data_http_basic_discover(self): + self.requests_mock.get( + BASE_URL, status_code=200, json=V3_VERSION_LIST) + self.requests_mock.get( + V3_URL, status_code=200, json=V3_VERSION_ENTRY) + + plugin = http_basic.HTTPBasicAuth(endpoint=V3_URL) + data = plugin.get_endpoint_data(self.session) + + self.assertEqual(data.api_version, (3, 0)) + self.assertEqual(data.url, V3_URL) + self.assertEqual(plugin.get_api_major_version(self.session), (3, 0)) + self.assertEqual(plugin.get_endpoint(self.session), V3_URL) + def test_endpoint_data_http_basic_no_discover(self): plugin = http_basic.HTTPBasicAuth(endpoint=V3_URL) data = plugin.get_endpoint_data( @@ -786,13 +818,8 @@ class VersionDataTests(utils.TestCase): self.assertEqual(data.api_version, (3, 0)) self.assertEqual(data.url, V3_URL) - self.assertEqual( - plugin.get_api_major_version( - self.session, endpoint_override=V3_URL), - (3, 0)) - self.assertEqual( - plugin.get_endpoint(self.session, endpoint_override=V3_URL), - V3_URL) + self.assertEqual(plugin.get_api_major_version(self.session), (3, 0)) + self.assertEqual(plugin.get_endpoint(self.session), V3_URL) def test_endpoint_data_http_basic_override_no_discover(self): plugin = http_basic.HTTPBasicAuth() @@ -810,6 +837,22 @@ class VersionDataTests(utils.TestCase): V3_URL) def test_endpoint_data_noauth_adapter(self): + self.requests_mock.get( + BASE_URL, status_code=200, json=V3_VERSION_LIST) + self.requests_mock.get( + V3_URL, status_code=200, json=V3_VERSION_ENTRY) + + client = adapter.Adapter( + session.Session(noauth.NoAuth()), + endpoint_override=BASE_URL) + data = client.get_endpoint_data() + + self.assertEqual(data.api_version, (3, 0)) + self.assertEqual(data.url, V3_URL) + self.assertEqual(client.get_api_major_version(), (3, 0)) + self.assertEqual(client.get_endpoint(), BASE_URL) + + def test_endpoint_data_noauth_versioned_adapter(self): mock = self.requests_mock.get( V3_URL, status_code=200, json=V3_VERSION_ENTRY) diff --git a/releasenotes/notes/noauth-discovery-c26d82a32c36d41d.yaml b/releasenotes/notes/noauth-discovery-c26d82a32c36d41d.yaml new file mode 100644 index 00000000..4a67aed8 --- /dev/null +++ b/releasenotes/notes/noauth-discovery-c26d82a32c36d41d.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixes ``get_api_major_version`` for non-keystone authentication methods + when the provided endpoint is not versioned.