From 8c483411697065e8708f1c36fdd1c877d70aae0b Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Sat, 23 Jan 2021 12:18:08 +0900 Subject: [PATCH] Allow specifying region of barbican endpoint This change introduces a new option to define the region to which the Barbican endpoint belongs. This is required if the deployment has multiple regions and a single Keystone instance stores multiple Barbican endpoints for different regions. This change also ensures that the same interface and region are used in endpoint detection and api version detection. Change-Id: If2c0055d45922937e259a8f22f5879c9faa41e35 --- castellan/key_manager/barbican_key_manager.py | 18 ++- .../key_manager/test_barbican_key_manager.py | 128 +++++++++++++++++- ...n-name-config-option-31bec809292302b8.yaml | 7 + 3 files changed, 147 insertions(+), 6 deletions(-) create mode 100644 releasenotes/notes/use-barbican-region-name-config-option-31bec809292302b8.yaml diff --git a/castellan/key_manager/barbican_key_manager.py b/castellan/key_manager/barbican_key_manager.py index 1b545ccb..374bd552 100644 --- a/castellan/key_manager/barbican_key_manager.py +++ b/castellan/key_manager/barbican_key_manager.py @@ -77,6 +77,9 @@ _barbican_opts = [ choices=['public', 'internal', 'admin'], help='Specifies the type of endpoint. Allowed values are: ' 'public, private, and admin'), + cfg.StrOpt('barbican_region_name', + default=None, + help='Specifies the region of the chosen endpoint.'), ] @@ -194,20 +197,25 @@ class BarbicanKeyManager(key_manager.KeyManager): elif getattr(auth, 'service_catalog', None): endpoint_data = auth.service_catalog.endpoint_data_for( service_type='key-manager', - interface=barbican.barbican_endpoint_type) + interface=barbican.barbican_endpoint_type, + region_name=barbican.barbican_region_name) return endpoint_data.url else: service_parameters = {'service_type': 'key-manager', - 'interface': barbican.barbican_endpoint_type} + 'interface': barbican.barbican_endpoint_type, + 'region_name': barbican.barbican_region_name} return auth.get_endpoint(sess, **service_parameters) def _create_base_url(self, auth, sess, endpoint): + barbican = self.conf.barbican api_version = None - if self.conf.barbican.barbican_api_version: - api_version = self.conf.barbican.barbican_api_version + if barbican.barbican_api_version: + api_version = barbican.barbican_api_version elif getattr(auth, 'service_catalog', None): endpoint_data = auth.service_catalog.endpoint_data_for( - service_type='key-manager') + service_type='key-manager', + interface=barbican.barbican_endpoint_type, + region_name=barbican.barbican_region_name) api_version = endpoint_data.api_version elif getattr(auth, 'get_discovery', None): discovery = auth.get_discovery(sess, url=endpoint) diff --git a/castellan/tests/unit/key_manager/test_barbican_key_manager.py b/castellan/tests/unit/key_manager/test_barbican_key_manager.py index 4d6c9bb5..ac4a44b0 100644 --- a/castellan/tests/unit/key_manager/test_barbican_key_manager.py +++ b/castellan/tests/unit/key_manager/test_barbican_key_manager.py @@ -76,6 +76,93 @@ class BarbicanKeyManagerTestCase(test_key_manager.KeyManagerTestCase): self.key_mgr._barbican_client = self.mock_barbican self.key_mgr._current_context = self.ctxt + def test_barbican_endpoint(self): + endpoint_data = mock.Mock() + endpoint_data.url = 'http://localhost:9311' + + auth = mock.Mock(spec=['service_catalog']) + auth.service_catalog.endpoint_data_for.return_value = endpoint_data + + endpoint = self.key_mgr._get_barbican_endpoint(auth, mock.Mock()) + self.assertEqual(endpoint, 'http://localhost:9311') + auth.service_catalog.endpoint_data_for.assert_called_once_with( + service_type='key-manager', interface='public', + region_name=None) + + def test_barbican_endpoint_with_endpoint_type(self): + self.key_mgr.conf.barbican.barbican_endpoint_type = 'internal' + + endpoint_data = mock.Mock() + endpoint_data.url = 'http://localhost:9311' + + auth = mock.Mock(spec=['service_catalog']) + auth.service_catalog.endpoint_data_for.return_value = endpoint_data + + endpoint = self.key_mgr._get_barbican_endpoint(auth, mock.Mock()) + self.assertEqual(endpoint, 'http://localhost:9311') + auth.service_catalog.endpoint_data_for.assert_called_once_with( + service_type='key-manager', interface='internal', + region_name=None) + + def test_barbican_endpoint_with_region_name(self): + self.key_mgr.conf.barbican.barbican_region_name = 'regionOne' + + endpoint_data = mock.Mock() + endpoint_data.url = 'http://localhost:9311' + + auth = mock.Mock(spec=['service_catalog']) + auth.service_catalog.endpoint_data_for.return_value = endpoint_data + + endpoint = self.key_mgr._get_barbican_endpoint(auth, mock.Mock()) + self.assertEqual(endpoint, 'http://localhost:9311') + auth.service_catalog.endpoint_data_for.assert_called_once_with( + service_type='key-manager', interface='public', + region_name='regionOne') + + def test_barbican_endpoint_from_config(self): + self.key_mgr.conf.barbican.barbican_endpoint = 'http://localhost:9311' + + endpoint = self.key_mgr._get_barbican_endpoint( + mock.Mock(), mock.Mock()) + self.assertEqual(endpoint, 'http://localhost:9311') + + def test_barbican_endpoint_by_get_endpoint(self): + auth = mock.Mock(spec=['get_endppint']) + sess = mock.Mock() + auth.get_endpoint = mock.Mock(return_value='http://localhost:9311') + + endpoint = self.key_mgr._get_barbican_endpoint(auth, sess) + self.assertEqual(endpoint, 'http://localhost:9311') + auth.get_endpoint.assert_called_once_with( + sess, service_type='key-manager', interface='public', + region_name=None) + + def test_barbican_endpoint_by_get_endpoint_with_endpoint_type(self): + self.key_mgr.conf.barbican.barbican_endpoint_type = 'internal' + + auth = mock.Mock(spec=['get_endppint']) + sess = mock.Mock() + auth.get_endpoint = mock.Mock(return_value='http://localhost:9311') + + endpoint = self.key_mgr._get_barbican_endpoint(auth, sess) + self.assertEqual(endpoint, 'http://localhost:9311') + auth.get_endpoint.assert_called_once_with( + sess, service_type='key-manager', interface='internal', + region_name=None) + + def test_barbican_endpoint_by_get_endpoint_with_region_name(self): + self.key_mgr.conf.barbican.barbican_region_name = 'regionOne' + + auth = mock.Mock(spec=['get_endppint']) + sess = mock.Mock() + auth.get_endpoint = mock.Mock(return_value='http://localhost:9311') + + endpoint = self.key_mgr._get_barbican_endpoint(auth, sess) + self.assertEqual(endpoint, 'http://localhost:9311') + auth.get_endpoint.assert_called_once_with( + sess, service_type='key-manager', interface='public', + region_name='regionOne') + def test_base_url_old_version(self): version = "v1" self.key_mgr.conf.barbican.barbican_api_version = version @@ -108,7 +195,46 @@ class BarbicanKeyManagerTestCase(test_key_manager.KeyManagerTestCase): endpoint) self.assertEqual(endpoint + "/" + endpoint_data.api_version, base_url) auth.service_catalog.endpoint_data_for.assert_called_once_with( - service_type='key-manager') + service_type='key-manager', interface='public', + region_name=None) + + def test_base_url_service_catalog_with_endpoint_type(self): + self.key_mgr.conf.barbican.barbican_endpoint_type = 'internal' + + endpoint_data = mock.Mock() + endpoint_data.api_version = 'v321' + + auth = mock.Mock(spec=['service_catalog']) + auth.service_catalog.endpoint_data_for.return_value = endpoint_data + + endpoint = "http://localhost/key_manager" + + base_url = self.key_mgr._create_base_url(auth, + mock.Mock(), + endpoint) + self.assertEqual(endpoint + "/" + endpoint_data.api_version, base_url) + auth.service_catalog.endpoint_data_for.assert_called_once_with( + service_type='key-manager', interface='internal', + region_name=None) + + def test_base_url_service_catalog_with_region_name(self): + self.key_mgr.conf.barbican.barbican_region_name = 'regionOne' + + endpoint_data = mock.Mock() + endpoint_data.api_version = 'v321' + + auth = mock.Mock(spec=['service_catalog']) + auth.service_catalog.endpoint_data_for.return_value = endpoint_data + + endpoint = "http://localhost/key_manager" + + base_url = self.key_mgr._create_base_url(auth, + mock.Mock(), + endpoint) + self.assertEqual(endpoint + "/" + endpoint_data.api_version, base_url) + auth.service_catalog.endpoint_data_for.assert_called_once_with( + service_type='key-manager', interface='public', + region_name='regionOne') def test_base_url_raise_exception(self): auth = mock.Mock(spec=['get_discovery']) diff --git a/releasenotes/notes/use-barbican-region-name-config-option-31bec809292302b8.yaml b/releasenotes/notes/use-barbican-region-name-config-option-31bec809292302b8.yaml new file mode 100644 index 00000000..03544b06 --- /dev/null +++ b/releasenotes/notes/use-barbican-region-name-config-option-31bec809292302b8.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + The new ``[barbican] barbican_region_name`` option has been added. + This parameter is used to determine the proper Barbican endpoint in + the multi-region deployment which has a different Barbican endpoint in + each region.