From 186f95b33e980aa90cc8f7a96c45be47b897e352 Mon Sep 17 00:00:00 2001 From: Alex Kavanagh Date: Thu, 3 Aug 2023 11:19:04 +0100 Subject: [PATCH] Fix broken v4 caching due to leader-get asymmetry leader-get decodes using json, but leader-set just sets the keys. This wasn't taken into consideration when fetching all the keys to filter for cached keys when a relation is leaving. This is resolved in this patch. func-test-pr: https://github.com/openstack-charmers/zaza-openstack-tests/pull/1153 Change-Id: I2d44ec0c43c1ecffd9ac77a1162ead4e4a01aabe (cherry picked from commit d925ac756638ed043e33a7b47a2681dfcd8900ce) (cherry picked from commit 0a18ac23ce295c14789e99f7802efc51438d10aa) --- src/lib/charm/vault_pki.py | 9 ++++++++- unit_tests/test_lib_charm_vault_pki.py | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/lib/charm/vault_pki.py b/src/lib/charm/vault_pki.py index f0a4f99..33e3f4f 100644 --- a/src/lib/charm/vault_pki.py +++ b/src/lib/charm/vault_pki.py @@ -565,7 +565,14 @@ class CertCache: """ value = hookenv.leader_get(key) if value: - return json.loads(value) + if key is not None: + # load the value that was json serialised in _store() + return json.loads(value) + else: + # due to a weird asymetry been leader_set and leader_get, + # leader_get() already deserialises as json so if no key was + # specified, it's already been deserialised. + return value return "" @staticmethod diff --git a/unit_tests/test_lib_charm_vault_pki.py b/unit_tests/test_lib_charm_vault_pki.py index a141476..ca866aa 100644 --- a/unit_tests/test_lib_charm_vault_pki.py +++ b/unit_tests/test_lib_charm_vault_pki.py @@ -856,6 +856,21 @@ class TestLibCharmVaultPKI(unit_tests.test_utils.CharmTestCase): self.assertEqual(vault_pki.CertCache(request)._fetch("mine"), 'the-value') + @patch.object(vault_pki.hookenv, 'leader_get') + def test_certcache__fetch_none(self, mock_leader_get): + request = self._default_request() + # due to weird asymetry between leader_get and leader_set, if no + # attribute is passed to leader_get() then the result is the + # deserialised set of key, values as a dictionary. + leader_get = { + 'a': 'an-a', + 'b': 'an-b', + } + + mock_leader_get.return_value = leader_get + self.assertEqual(vault_pki.CertCache(request)._fetch(None), leader_get) + mock_leader_get.assert_called_once_with(None) + @patch.object(vault_pki.hookenv, 'leader_set') def test_certcache__store(self, mock_leader_set): request = self._default_request()