From 3ff8427f773869616f52766eb7a3217e009c153c Mon Sep 17 00:00:00 2001 From: David Ames Date: Thu, 28 Feb 2019 15:22:30 +0100 Subject: [PATCH] Enable vault tls-certificates for SAML Mellon The charm assumed the use of ssl_cert and ssl_key. The current best practice is to deploy with vault and the tls-certificates relation. Enable tls-certificates relation aware configuration for the fid-service-provider relation. Change-Id: I5441359b1d60b07c6b47ca58b45a09c4b7ac886b --- hooks/keystone_hooks.py | 14 +++++++-- unit_tests/test_keystone_hooks.py | 47 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/hooks/keystone_hooks.py b/hooks/keystone_hooks.py index f3491301..d1247a0c 100755 --- a/hooks/keystone_hooks.py +++ b/hooks/keystone_hooks.py @@ -145,6 +145,7 @@ from charmhelpers.contrib.peerstorage import ( ) from charmhelpers.contrib.openstack.ip import ( ADMIN, + PUBLIC, resolve_address, ) @@ -759,12 +760,19 @@ def websso_trusted_dashboard_changed(): def update_keystone_fid_service_provider(relation_id=None): - tls_enabled = (config('ssl_cert') is not None and - config('ssl_key') is not None) + if relation_ids('certificates'): + tls_enabled = True + else: + tls_enabled = (config('ssl_cert') is not None and + config('ssl_key') is not None) + # NOTE: thedac Use resolve_address which checks host name, VIP and + # network bindings. Use PUBLIC for now. Possible TODO make this + # configurable? + hostname = resolve_address(endpoint_type=PUBLIC, override=True) # reactive endpoints implementation on the other side, hence # json-encoded values fid_settings = { - 'hostname': json.dumps(config('os-public-hostname')), + 'hostname': json.dumps(hostname), 'port': json.dumps(config('service-port')), 'tls-enabled': json.dumps(tls_enabled), } diff --git a/unit_tests/test_keystone_hooks.py b/unit_tests/test_keystone_hooks.py index 856129ab..6b90a9e1 100644 --- a/unit_tests/test_keystone_hooks.py +++ b/unit_tests/test_keystone_hooks.py @@ -829,6 +829,7 @@ class KeystoneRelationTests(CharmTestCase): self.is_leader.return_value = True self.is_db_ready.return_value = True is_db_initialised.return_value = True + self.resolve_address.return_value = "10.0.0.10" mock_kv = MagicMock() mock_kv.get.return_value = None self.unitdata.kv.return_value = mock_kv @@ -871,6 +872,7 @@ class KeystoneRelationTests(CharmTestCase): mock_kv.get.return_value = None self.unitdata.kv.return_value = mock_kv is_unit_paused_set.return_value = False + self.resolve_address.return_value = "10.0.0.10" hooks.keystone_fid_service_provider_changed() @@ -884,6 +886,51 @@ class KeystoneRelationTests(CharmTestCase): 'nonce2') self.assertTrue(mock_kv.flush.called) + def test_update_keystone_fid_service_provider_no_tls(self): + self.relation_ids.return_value = [] + public_addr = "10.0.0.10" + self.resolve_address.return_value = public_addr + relation_id = "keystone-fid-service-provider-certificates:5" + relation_settings = { + 'hostname': '"{}"'.format(public_addr), + 'port': '5000', + 'tls-enabled': 'false' + } + hooks.update_keystone_fid_service_provider(relation_id=relation_id) + self.relation_set.assert_called_once_with( + relation_id=relation_id, relation_settings=relation_settings) + + def test_update_keystone_fid_service_provider_tls_certificates_relation( + self): + self.relation_ids.return_value = ["certficates:9"] + public_addr = "10.0.0.10" + self.resolve_address.return_value = public_addr + relation_id = "keystone-fid-service-provider-certificates:5" + relation_settings = { + 'hostname': '"{}"'.format(public_addr), + 'port': '5000', + 'tls-enabled': 'true' + } + hooks.update_keystone_fid_service_provider(relation_id=relation_id) + self.relation_set.assert_called_once_with( + relation_id=relation_id, relation_settings=relation_settings) + + def test_update_keystone_fid_service_provider_ssl_config(self): + self.test_config.set("ssl_cert", "CERTIFICATE") + self.test_config.set("ssl_key", "KEY") + self.relation_ids.return_value = [] + public_addr = "10.0.0.10" + self.resolve_address.return_value = public_addr + relation_id = "keystone-fid-service-provider-certificates:5" + relation_settings = { + 'hostname': '"{}"'.format(public_addr), + 'port': '5000', + 'tls-enabled': 'true' + } + hooks.update_keystone_fid_service_provider(relation_id=relation_id) + self.relation_set.assert_called_once_with( + relation_id=relation_id, relation_settings=relation_settings) + @patch.object(hooks, 'relation_set') @patch.object(hooks, 'get_certificate_request') def test_certs_joined(self, get_certificate_request, relation_set):