From d3b45edb2f044b42d3eadc31d5a13ae5a527f7b2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorsten=20Ro=C3=9Fner?= <thorsten.rossner.extern@zendis.de>
Date: Tue, 16 Jul 2024 10:47:56 +0200
Subject: [PATCH] feat(kcom.py): Support for custom oidc object definitions.

---
 .../keycloak-config-object-manager/kcom.py    | 28 ++++++++++---------
 .../lib/keycloak.py                           |  4 +--
 2 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/bootstrap-opendesk-keycloak/keycloak-config-object-manager/kcom.py b/bootstrap-opendesk-keycloak/keycloak-config-object-manager/kcom.py
index d927104..c2a88d1 100755
--- a/bootstrap-opendesk-keycloak/keycloak-config-object-manager/kcom.py
+++ b/bootstrap-opendesk-keycloak/keycloak-config-object-manager/kcom.py
@@ -1,5 +1,4 @@
 #!/usr/bin/python3
-# -*- coding: utf-8 -*-
 # SPDX-FileCopyrightText: 2023 Bundesministerium des Innern und für Heimat, PG ZenDiS "Projektgruppe für Aufbau ZenDiS"
 # SPDX-License-Identifier: Apache-2.0
 
@@ -30,16 +29,19 @@ kc = Keycloak(
 )
 
 # We enforce a certain order, as clientScopes should always be processed before clients.
-# fyi: clients get re-created on change, while clientScopes get updated.
+# We already recreate these objects to ensure they are in line with the provided config.
 for type in ['clientScopes', 'clients']:
-    type_config = config['config']['custom'][type]
-    logging.info(f"Processing {type}")
-    if type_config:
-        names = []
-        for object in type_config:
-              if 'name' not in object:
-                  sys.exit(f"! 'name' attribute is mandatory for objects but missing: {object}")
-              names.append(object['name'])
-              logging.info(f"Working on {type}: {object['name']}")
-              kc.create_or_recreate_object(type=type, data=object)
-        kc.reconcile_objecttype(type=type, names=names)
+    keep_names = []
+    for section in [ 'opendesk', 'custom' ]:
+        if type in config['config'][section]:
+            type_config = config['config'][section][type]
+            logging.info(f"Processing {type} from {section}")
+            for object in type_config:
+                if 'name' not in object:
+                    sys.exit(f"! 'name' attribute is mandatory for objects but missing: {object}")
+                keep_names.append(object['name'])
+                logging.info(f"Working on {type}: {object['name']}")
+                kc.create_or_recreate_object(type=type, data=object)
+        else:
+            logging.debug(f"No {type} found in {section}.")
+        kc.reconcile_objecttype(type=type, keep_names=keep_names)
diff --git a/bootstrap-opendesk-keycloak/keycloak-config-object-manager/lib/keycloak.py b/bootstrap-opendesk-keycloak/keycloak-config-object-manager/lib/keycloak.py
index 7abd05f..63b2601 100644
--- a/bootstrap-opendesk-keycloak/keycloak-config-object-manager/lib/keycloak.py
+++ b/bootstrap-opendesk-keycloak/keycloak-config-object-manager/lib/keycloak.py
@@ -103,10 +103,10 @@ class Keycloak:
         logging.warning(f"{type} object {name} not found")
         return None
 
-    def reconcile_objecttype(self, type, names = []):
+    def reconcile_objecttype(self, type, keep_names = []):
         typepath = self.__get_subpath(type)
         res = self.__api_call(subpath=typepath, method='get')
-        want_list = names + self.__get_defaultnames(type)
+        want_list = keep_names + self.__get_defaultnames(type)
         for object in res.json():
             if 'name' not in object:
                 logging.error(f"Object has no name defined, ignoring for reconciliation")
-- 
GitLab