1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2026-02-04 07:51:50 +00:00

11430: fix diff for keycloak client auth flow overrides

This commit is contained in:
Thomas Bargetz 2026-01-28 11:05:02 +01:00
parent 10250d9294
commit e69720eaba

View file

@ -1174,6 +1174,26 @@ def remove_optional_client_scopes(desired_client, before_client, realm, kc):
kc.delete_optional_clientscope(scope["id"], realm, desired_client["clientId"])
def merge_settings_without_absent_nulls(existing_settings, desired_settings):
"""
Merges existing and desired settings into a new dictionary while excluding null values in desired settings that are absent in the existing settings.
This ensures idempotency by treating absent keys in existing settings and null values in desired settings as equivalent, preventing unnecessary updates.
Args:
existing_settings (dict): Dictionary representing the current settings in Keycloak
desired_settings (dict): Dictionary representing the desired settings
Returns:
dict: A new dictionary containing all entries from existing_settings and desired_settings,
excluding null values in desired_settings whose corresponding keys are not present in existing_settings
"""
existing = existing_settings or {}
desired = desired_settings or {}
return {**existing, **{k: v for k, v in desired.items() if v is not None or k in existing}}
def main():
"""
Module execution
@ -1316,15 +1336,17 @@ def main():
if client_param == "protocol_mappers":
new_param_value = [{k: v for k, v in x.items() if v is not None} for x in new_param_value]
elif client_param == "authentication_flow_binding_overrides":
new_param_value = flow_binding_from_dict_to_model(new_param_value, realm, kc)
elif client_param == "attributes" and "attributes" in before_client:
attributes_copy = copy.deepcopy(before_client["attributes"])
# Merge client attributes while excluding null-valued attributes that are not present in Keycloak's response.
# This ensures idempotency by treating absent attributes and null attributes as equivalent.
attributes_copy.update(
{key: value for key, value in new_param_value.items() if value is not None or key in attributes_copy}
desired_flow_binding_overrides = flow_binding_from_dict_to_model(new_param_value, realm, kc)
existing_flow_binding_overrides = before_client.get("authenticationFlowBindingOverrides")
# ensures idempotency
new_param_value = merge_settings_without_absent_nulls(
existing_flow_binding_overrides, desired_flow_binding_overrides
)
new_param_value = attributes_copy
elif client_param == "attributes" and "attributes" in before_client:
desired_attributes = new_param_value
existing_attributes = copy.deepcopy(before_client["attributes"])
# ensures idempotency
new_param_value = merge_settings_without_absent_nulls(existing_attributes, desired_attributes)
elif client_param in ["clientScopesBehavior", "client_scopes_behavior"]:
continue