From 996036acd7b1376f0a378a407697afa28e5b2861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Guimar=C3=A3es=20de=20Medeiros?= Date: Tue, 5 May 2020 18:24:14 -0300 Subject: [PATCH] Add TLS context creation from config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch sets up the TLS context object based on the configuration options passed via oslo.config and adds it as an argument to be passed to the selected oslo.cache backend. Change-Id: I825b5c37b2c6a96b459e6cc162ba5d1254091f0f Signed-off-by: Moisés Guimarães de Medeiros --- oslo_cache/core.py | 22 ++++++ oslo_cache/tests/unit/test_cache_basics.py | 78 ++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/oslo_cache/core.py b/oslo_cache/core.py index 384e42f6..23b5f6d4 100644 --- a/oslo_cache/core.py +++ b/oslo_cache/core.py @@ -34,6 +34,7 @@ The library has special public value for nonexistent or expired keys called from oslo_cache import core NO_VALUE = core.NO_VALUE """ +import ssl import dogpile.cache from dogpile.cache import api @@ -145,6 +146,27 @@ def _build_cache_config(conf): value = getattr(conf.cache, 'memcache_' + arg) conf_dict['%s.arguments.%s' % (prefix, arg)] = value + if conf.cache.tls_enabled: + _LOG.debug('Oslo Cache TLS - CA: %s', conf.cache.tls_cafile) + tls_context = ssl.create_default_context(cafile=conf.cache.tls_cafile) + + if conf.cache.tls_certfile is not None: + _LOG.debug('Oslo Cache TLS - cert: %s', conf.cache.tls_certfile) + _LOG.debug('Oslo Cache TLS - key: %s', conf.cache.tls_keyfile) + tls_context.load_cert_chain( + conf.cache.tls_certfile, + conf.cache.tls_keyfile, + ) + + if conf.cache.tls_allowed_ciphers is not None: + _LOG.debug( + 'Oslo Cache TLS - ciphers: %s', + conf.cache.tls_allowed_ciphers, + ) + tls_context.set_ciphers(conf.cache.tls_allowed_ciphers) + + conf_dict['%s.arguments.tls_context' % prefix] = tls_context + return conf_dict diff --git a/oslo_cache/tests/unit/test_cache_basics.py b/oslo_cache/tests/unit/test_cache_basics.py index 781a4389..4d9ae5cb 100644 --- a/oslo_cache/tests/unit/test_cache_basics.py +++ b/oslo_cache/tests/unit/test_cache_basics.py @@ -14,6 +14,7 @@ # under the License. import copy +import ssl import time from unittest import mock @@ -274,6 +275,83 @@ class CacheRegionTest(test_cache.BaseTestCase): _opts._DEFAULT_BACKEND, config_dict['test_prefix.backend']) + def test_cache_dictionary_config_builder_tls_disabled(self): + """Validate the backend is reset to default if caching is disabled.""" + self.config_fixture.config(group='cache', + enabled=True, + config_prefix='test_prefix', + backend='oslo_cache.dict', + tls_cafile='path_to_ca_file', + tls_keyfile='path_to_key_file', + tls_certfile='path_to_cert_file', + tls_allowed_ciphers='allowed_ciphers') + + with mock.patch.object(ssl, 'create_default_context'): + config_dict = cache._build_cache_config(self.config_fixture.conf) + + self.assertFalse(self.config_fixture.conf.cache.tls_enabled) + ssl.create_default_context.assert_not_called() + self.assertNotIn('test_prefix.arguments.tls_context', config_dict) + + def test_cache_dictionary_config_builder_tls_enabled(self): + """Validate the backend is reset to default if caching is disabled.""" + self.config_fixture.config(group='cache', + enabled=True, + config_prefix='test_prefix', + backend='oslo_cache.dict', + tls_enabled=True) + + fake_context = mock.Mock() + with mock.patch.object(ssl, 'create_default_context', + return_value=fake_context): + config_dict = cache._build_cache_config(self.config_fixture.conf) + + self.assertTrue(self.config_fixture.conf.cache.tls_enabled) + + ssl.create_default_context.assert_called_with(cafile=None) + fake_context.load_cert_chain.assert_not_called() + fake_context.set_ciphers.assert_not_called() + + self.assertEqual( + fake_context, + config_dict['test_prefix.arguments.tls_context'], + ) + + def test_cache_dictionary_config_builder_tls_enabled_with_config(self): + """Validate the backend is reset to default if caching is disabled.""" + self.config_fixture.config(group='cache', + enabled=True, + config_prefix='test_prefix', + backend='oslo_cache.dict', + tls_enabled=True, + tls_cafile='path_to_ca_file', + tls_keyfile='path_to_key_file', + tls_certfile='path_to_cert_file', + tls_allowed_ciphers='allowed_ciphers') + + fake_context = mock.Mock() + with mock.patch.object(ssl, 'create_default_context', + return_value=fake_context): + config_dict = cache._build_cache_config(self.config_fixture.conf) + + self.assertTrue(self.config_fixture.conf.cache.tls_enabled) + + ssl.create_default_context.assert_called_with( + cafile='path_to_ca_file', + ) + fake_context.load_cert_chain.assert_called_with( + 'path_to_cert_file', + 'path_to_key_file', + ) + fake_context.set_ciphers.assert_called_with( + 'allowed_ciphers' + ) + + self.assertEqual( + fake_context, + config_dict['test_prefix.arguments.tls_context'], + ) + def test_cache_debug_proxy(self): single_value = 'Test Value' single_key = 'testkey'