From 31201ce71c7c7650d149cff8db73fe14287af20b Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Thu, 1 Feb 2024 00:19:23 +0900 Subject: [PATCH] Automate TLS certificates settings for redis backend This adds support for configuring certificate/key files used for TLS connection with Redis using the existing tls_* options. example) [cache] backend=dogpile.cache.backend.redis backend_arguments=url:rediss://:a_big_secret@localhost:2679 tls_enabled=True tls_cafile = /etc/pki/tls/certs/ca-bundle.crt Change-Id: I2ab38b8c88274cb4908791eea8212a79e3d524a2 --- oslo_cache/core.py | 23 ++++++++ oslo_cache/tests/unit/test_cache_basics.py | 54 +++++++++++++++++++ .../notes/redis-ssl-ca14b4b99c2e5a84.yaml | 11 ++++ 3 files changed, 88 insertions(+) create mode 100644 releasenotes/notes/redis-ssl-ca14b4b99c2e5a84.yaml diff --git a/oslo_cache/core.py b/oslo_cache/core.py index e61ba838..2ae6e087 100644 --- a/oslo_cache/core.py +++ b/oslo_cache/core.py @@ -206,6 +206,29 @@ def _build_cache_config(conf): tls_context.set_ciphers(conf.cache.tls_allowed_ciphers) conf_dict['%s.arguments.tls_context' % prefix] = tls_context + elif conf.cache.backend in ('dogpile.cache.redis',): + if conf.cache.tls_allowed_ciphers is not None: + raise exception.ConfigurationError( + "Limiting allowed ciphers is not supported by " + "the %s backend" % conf.cache.backend) + if conf.cache.enforce_fips_mode: + raise exception.ConfigurationError( + "FIPS mode is not supported by the %s backend" % + conf.cache.backend) + + conn_kwargs = {} + if conf.cache.tls_cafile is not None: + _LOG.debug('Oslo Cache TLS - CA: %s', conf.cache.tls_cafile) + conn_kwargs['ssl_ca_certs'] = 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) + conn_kwargs.update({ + 'ssl_certfile': conf.cache.tls_certfile, + 'ssl_keyfile': conf.cache.tls_keyfile + }) + conf_dict['%s.arguments.connection_kwargs' % prefix] = conn_kwargs else: msg = _( "TLS setting via [cache] tls_enabled is not supported by this " diff --git a/oslo_cache/tests/unit/test_cache_basics.py b/oslo_cache/tests/unit/test_cache_basics.py index 3f89ea1c..eb2181a3 100644 --- a/oslo_cache/tests/unit/test_cache_basics.py +++ b/oslo_cache/tests/unit/test_cache_basics.py @@ -294,6 +294,23 @@ class CacheRegionTest(test_cache.BaseTestCase): ssl.create_default_context.assert_not_called() self.assertNotIn('test_prefix.arguments.tls_context', config_dict) + def test_cache_dictionary_config_builder_tls_disabled_redis(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='dogpile.cache.redis', + tls_cafile='path_to_ca_file', + tls_keyfile='path_to_key_file', + tls_certfile='path_to_cert_file', + tls_allowed_ciphers='allowed_ciphers') + + config_dict = cache._build_cache_config(self.config_fixture.conf) + + self.assertFalse(self.config_fixture.conf.cache.tls_enabled) + self.assertNotIn('test_prefix.arguments.connection_kwargs', + 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', @@ -318,6 +335,30 @@ class CacheRegionTest(test_cache.BaseTestCase): config_dict['test_prefix.arguments.tls_context'], ) + def test_cache_dictionary_config_builder_tls_enabled_redis(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='dogpile.cache.redis', + tls_enabled=True, + tls_cafile='path_to_ca_file', + tls_keyfile='path_to_key_file', + tls_certfile='path_to_cert_file') + + config_dict = cache._build_cache_config(self.config_fixture.conf) + + self.assertTrue(self.config_fixture.conf.cache.tls_enabled) + self.assertIn('test_prefix.arguments.connection_kwargs', + config_dict) + self.assertEqual( + { + 'ssl_ca_certs': 'path_to_ca_file', + 'ssl_keyfile': 'path_to_key_file', + 'ssl_certfile': 'path_to_cert_file' + }, + config_dict['test_prefix.arguments.connection_kwargs']) + @mock.patch('oslo_cache.core._LOG') def test_cache_dictionary_config_builder_fips_mode_supported(self, log): """Validate the FIPS mode is supported.""" @@ -357,6 +398,19 @@ class CacheRegionTest(test_cache.BaseTestCase): cache._build_cache_config, self.config_fixture.conf) + def test_cache_dictionary_config_builder_fips_mode_unsupported_redis(self): + """Validate the FIPS mode is not supported.""" + self.config_fixture.config(group='cache', + enabled=True, + config_prefix='test_prefix', + backend='dogpile.cache.redis', + tls_enabled=True, + enforce_fips_mode=True) + + self.assertRaises(exception.ConfigurationError, + cache._build_cache_config, + self.config_fixture.conf) + def test_cache_dictionary_config_builder_tls_enabled_unsupported(self): """Validate the tls_enabled opiton is not supported..""" self.config_fixture.config(group='cache', diff --git a/releasenotes/notes/redis-ssl-ca14b4b99c2e5a84.yaml b/releasenotes/notes/redis-ssl-ca14b4b99c2e5a84.yaml new file mode 100644 index 00000000..b414f45e --- /dev/null +++ b/releasenotes/notes/redis-ssl-ca14b4b99c2e5a84.yaml @@ -0,0 +1,11 @@ +--- +features: + - | + When the ``dogpile.cache.redis`` backend is used and + the ``[cache] tls_enable`` option is set to True, now the following + ``[cache]`` options set tls certificates and keys used for TLS + communication with Redis. + + - ``tls_cafile`` + - ``tls_certfile`` + - ``tls_keyfile``