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'