From 53dc8aefca425de275de16c8f54aacdddfc20e73 Mon Sep 17 00:00:00 2001 From: matt hope Date: Wed, 14 Feb 2024 13:38:35 +1100 Subject: [PATCH] Merge secrets instead of clashing If we have two credentials that would create/update the same secret (say, based on the "secret-name" metadata), the behaviour currently isn't ideal - it can depend on the order in which the credentials are returned in which values get created. Furthermore, if you have one credential creating a key for say, "token1", and the second credential creating key "token2" .. they dont get merged. So you'll have a kubernetes secret with either "token1" or "token2" depending on the ordering. That leads to .. disappointment and unexpected errors. Lets do something about that. - If two credentials are targeting the same Kuberentes secret, lets merge them together. - As the ordering can be inconsistent, lets support a metadata field "secret-merge-priority" for ordering. --- secretupdater/secretupdater/models.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/secretupdater/secretupdater/models.py b/secretupdater/secretupdater/models.py index aac325b..6bbfe2d 100644 --- a/secretupdater/secretupdater/models.py +++ b/secretupdater/secretupdater/models.py @@ -178,6 +178,11 @@ def _setup_confidant_client(service): def _parse_secret_collection(secret_collection, namespace): secrets = {} + # if the metadata 'secret-merge-priority' is set, then we can sort the + # collection on that, which means higher "priority" entries will + # override/replace if the secret key is the same. + secret_collection.sort(key=lambda element: element.get('metadata', {}).get("secret-merge-priority", "")) + for entry in secret_collection: secret = _parse_secret_entry(entry, namespace) @@ -187,7 +192,12 @@ def _parse_secret_collection(secret_collection, namespace): continue name = secret['metadata']['name'] - secrets[name] = secret + + # If we've got two entries to create the same secret, merge the data. + if name in secrets: + secrets[name]["data"] = {**secrets[name]["data"], **secret["data"]} + else: + secrets[name] = secret return secrets