diff --git a/changelogs/fragments/8761-keycloak_user_federation-sort-desired-and-after-mappers-by-name.yml b/changelogs/fragments/8761-keycloak_user_federation-sort-desired-and-after-mappers-by-name.yml new file mode 100644 index 0000000000..2d7d39345f --- /dev/null +++ b/changelogs/fragments/8761-keycloak_user_federation-sort-desired-and-after-mappers-by-name.yml @@ -0,0 +1,2 @@ +bugfixes: + - keycloak_user_federation - sort desired and after mapper list by name (analog to before mapper list) to minimize diff and make change detection more accurate (https://github.com/ansible-collections/community.general/pull/8761). \ No newline at end of file diff --git a/plugins/modules/keycloak_user_federation.py b/plugins/modules/keycloak_user_federation.py index 90760f7ce9..f80d694e07 100644 --- a/plugins/modules/keycloak_user_federation.py +++ b/plugins/modules/keycloak_user_federation.py @@ -883,7 +883,7 @@ def main(): # if user federation exists, get associated mappers if cid is not None and before_comp: - before_comp['mappers'] = sorted(kc.get_components(urlencode(dict(parent=cid)), realm), key=lambda x: x.get('name')) + before_comp['mappers'] = sorted(kc.get_components(urlencode(dict(parent=cid)), realm), key=lambda x: x.get('name') or '') # Build a proposed changeset from parameters given to this module changeset = {} @@ -924,6 +924,7 @@ def main(): if changeset.get('mappers') is None: changeset['mappers'] = list() changeset['mappers'].append(new_mapper) + changeset['mappers'] = sorted(changeset['mappers'], key=lambda x: x.get('name') or '') # to keep unspecified existing mappers we add them to the desired mappers list, unless they're already present if not module.params['remove_unspecified_mappers'] and 'mappers' in before_comp: @@ -1039,7 +1040,7 @@ def main(): kc.create_component(mapper, realm) after_comp = kc.get_component(cid, realm) - after_comp['mappers'] = kc.get_components(urlencode(dict(parent=cid)), realm) + after_comp['mappers'] = sorted(kc.get_components(urlencode(dict(parent=cid)), realm), key=lambda x: x.get('name') or '') after_comp_sanitized = sanitize(after_comp) before_comp_sanitized = sanitize(before_comp) result['end_state'] = after_comp_sanitized