From 13e14d2a909a4c36f4e388f6694c786e05c68915 Mon Sep 17 00:00:00 2001 From: Claire Lefrancq Date: Mon, 14 Apr 2025 11:31:20 +0200 Subject: [PATCH] Add normalization to suppress false positives for booleans in diff mode --- plugins/module_utils/identity/keycloak/keycloak.py | 6 ++++++ plugins/modules/keycloak_client.py | 5 ++++- plugins/modules/keycloak_clientscope.py | 5 ++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/plugins/module_utils/identity/keycloak/keycloak.py b/plugins/module_utils/identity/keycloak/keycloak.py index 2595e4ae5cf..f96fe218031 100644 --- a/plugins/module_utils/identity/keycloak/keycloak.py +++ b/plugins/module_utils/identity/keycloak/keycloak.py @@ -133,6 +133,12 @@ def nonify_absences(before, desired): elif isinstance(v, dict): nonify_absences(v, desired[k]) +# Normalize booleans in dictionaries to 'true' or 'false' to suppress false positive diffs +def normalize_diffmode_boolean(dictionary): + normalized_dictionary = {} + for k, v in dictionary.items(): + normalized_dictionary[k] = str(v).lower() if str(v) in ['True', 'False'] else v + return normalized_dictionary class KeycloakError(Exception): pass diff --git a/plugins/modules/keycloak_client.py b/plugins/modules/keycloak_client.py index db4a8048d8a..c66dd561802 100644 --- a/plugins/modules/keycloak_client.py +++ b/plugins/modules/keycloak_client.py @@ -716,6 +716,7 @@ nonify_absences, keycloak_argument_spec, get_token, + normalize_diffmode_boolean, KeycloakError, ) from ansible.module_utils.basic import AnsibleModule @@ -734,7 +735,7 @@ def normalise_cr(clientrep, remove_ids=False): clientrep = clientrep.copy() if "attributes" in clientrep: - clientrep["attributes"] = dict(sorted(clientrep["attributes"].items())) + clientrep["attributes"] = normalize_diffmode_boolean(dict(sorted(clientrep["attributes"].items()))) # Ignore unchangeable attributes attribute_ignorelist = ["saml.artifact.binding.identifier", "client.secret.creation.time"] for attr in attribute_ignorelist: @@ -752,6 +753,8 @@ def normalise_cr(clientrep, remove_ids=False): for mapper in clientrep["protocolMappers"]: if remove_ids: mapper.pop("id", None) + if 'config' in mapper: + mapper['config'] = normalize_diffmode_boolean(mapper['config']) # Set to a default value. mapper["consentRequired"] = mapper.get("consentRequired", False) diff --git a/plugins/modules/keycloak_clientscope.py b/plugins/modules/keycloak_clientscope.py index 8ea63789f63..a2ec838a4ec 100644 --- a/plugins/modules/keycloak_clientscope.py +++ b/plugins/modules/keycloak_clientscope.py @@ -295,7 +295,7 @@ ''' from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import KeycloakAPI, camel, \ - keycloak_argument_spec, get_token, KeycloakError, is_struct_included + keycloak_argument_spec, get_token, KeycloakError, is_struct_included, normalize_diffmode_boolean from ansible.module_utils.basic import AnsibleModule import copy @@ -305,6 +305,9 @@ def normalize_checkmode(clientscoperep): result['attributes'] = {key:result['attributes'][key] for key in sorted(result['attributes'].keys())} if 'protocolMappers' in result: result['protocolMappers'] = list(sorted(result['protocolMappers'], key= lambda mapper: mapper.get('name'))) + for mapper in result['protocolMappers']: + if 'config' in mapper: + mapper['config'] = normalize_diffmode_boolean(mapper['config']) return dict((k, v) for k, v in result.items() if v) def sanitize_cr(clientscoperep):