Files
computer-playbook/roles/web-app-keycloak/tasks/assert/01_ldap.yml
kevinveenbirkenbachandClaude Opus 4.8 4039313266 refactor(tasks): enforce and apply a single task-file numbering scheme
Add tests/lint/repository/test_task_file_numbering.py: numbered task
files use exactly two leading digits, a numbered *_core.yml must be
00_core.yml, per directory the numbers are unique/consecutive and start
at 01 (00 with a core file), numbered includes appear in ascending
order, and shared helpers live in tasks/utils/ instead of the numbered
chain.

Apply it across every role: rename NN_core.yml to 00_core.yml with a
consecutive down-shift of the siblings, move letter-suffix children into
a subdirectory named after their parent task, relocate helpers included
from more than one place into tasks/utils/, and update every reference
(include_tasks, path_absolute, .ansible-lint-ignore, requirement docs).
Legacy narration comments in the touched files are deleted; the upstream
xwiki.properties reference block opts out via nocheck. The unused
MAILU_IP6_PUBLIC var (only ever named in now-removed comments) is dropped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:01:31 +02:00

149 lines
4.9 KiB
YAML

---
#
# Read-only assertions for LDAP configuration in Keycloak.
# Ensures:
# - LDAP UserStorageProvider exists
# - ldap-roles mapper exists exactly once
# - groups.path is consistent
# - top-level group for groups.path exists
#
# This file must NEVER modify state.
- name: ✅ Assert | Initialize LDAP assert variables
set_fact:
ldap_cmp_id_assert: ""
desired_group_mapper_raw_assert: {}
desired_groups_path_assert: ""
desired_groups_top_assert: ""
grp_mapper_ids_assert: []
changed_when: false
- name: ✅ Assert | Fetch components (JSON)
shell: >
{{ KEYCLOAK_EXEC_KCADM }} get components -r {{ KEYCLOAK_REALM }} --format json
register: kc_components_assert
changed_when: false
- name: ✅ Assert | Resolve LDAP component id (client-side filter)
set_fact:
ldap_cmp_id_assert: >-
{{
(
kc_components_assert.stdout | kcadm_json
| selectattr('providerType','equalto','org.keycloak.storage.UserStorageProvider')
| selectattr('providerId','equalto','ldap')
| selectattr('name','equalto', KEYCLOAK_LDAP_CMP_NAME)
| map(attribute='id')
| list
| first
| default('')
) | string | trim
}}
changed_when: false
- name: ✅ Assert | LDAP component exists
assert:
that:
- ldap_cmp_id_assert not in ["", "null"]
fail_msg: "LDAP component '{{ KEYCLOAK_LDAP_CMP_NAME }}' not found in realm '{{ KEYCLOAK_REALM }}'."
- name: ✅ Assert | Load desired ldap-roles mapper from dictionary
set_fact:
desired_group_mapper_raw_assert: >-
{{
(
KEYCLOAK_DICTIONARY_REALM.components['org.keycloak.storage.UserStorageProvider']
| selectattr('name','equalto', KEYCLOAK_LDAP_CMP_NAME)
| list | first | default({})
).subComponents['org.keycloak.storage.ldap.mappers.LDAPStorageMapper']
| default([])
| selectattr('name','equalto','ldap-roles')
| list | first | default({})
}}
changed_when: false
- name: ✅ Assert | ldap-roles mapper exists in dictionary
assert:
that:
- desired_group_mapper_raw_assert | length > 0
fail_msg: "'ldap-roles' mapper missing in KEYCLOAK_DICTIONARY_REALM."
- name: ✅ Assert | Extract desired groups.path
when: desired_group_mapper_raw_assert | length > 0
set_fact:
desired_groups_path_assert: "{{ (desired_group_mapper_raw_assert.config['groups.path'] | default([])) | first | default('') | trim }}"
desired_groups_top_assert: "{{ desired_groups_path_assert.lstrip('/') | split('/') | first | default('') }}"
changed_when: false
- name: ✅ Assert | groups.path defined when mapper exists
when: desired_group_mapper_raw_assert | length > 0
assert:
that:
- desired_groups_path_assert != ""
fail_msg: "ldap-roles mapper exists but config.groups.path is empty."
- name: ✅ Assert | List ldap-roles mappers under LDAP component (client-side)
set_fact:
grp_mapper_ids_assert: >-
{{
(
kc_components_assert.stdout | kcadm_json
| selectattr('parentId','equalto', ldap_cmp_id_assert)
| selectattr('providerId','equalto','group-ldap-mapper')
| selectattr('providerType','equalto','org.keycloak.storage.ldap.mappers.LDAPStorageMapper')
| selectattr('name','equalto','ldap-roles')
| map(attribute='id')
| list
)
}}
changed_when: false
- name: ✅ Assert | Exactly one ldap-roles mapper exists
assert:
that:
- grp_mapper_ids_assert | length == 1
fail_msg: >-
Expected exactly ONE 'ldap-roles' mapper under LDAP component,
found {{ grp_mapper_ids_assert | length }}: {{ grp_mapper_ids_assert }}
- name: ✅ Assert | Verify top-level group exists when groups.path is set
when: desired_groups_top_assert | length > 0
block:
- name: ✅ Assert | Fetch groups (JSON)
shell: >
{{ KEYCLOAK_EXEC_KCADM }} get groups -r {{ KEYCLOAK_REALM }} --format json
register: kc_groups_assert
changed_when: false
- name: ✅ Assert | Resolve top-level group id
set_fact:
groups_top_id_assert: >-
{{
(
kc_groups_assert.stdout | kcadm_json
| selectattr('name','equalto', desired_groups_top_assert)
| map(attribute='id')
| list
| first
| default('')
) | string | trim
}}
changed_when: false
- name: ✅ Assert | Top-level group exists
assert:
that:
- groups_top_id_assert not in ["", "null"]
fail_msg: >-
groups.path='{{ desired_groups_path_assert }}' requires top-level group
'{{ desired_groups_top_assert }}', but it does not exist.
- name: ✅ Assert | LDAP summary
debug:
msg:
ldap_component_id: "{{ ldap_cmp_id_assert }}"
ldap_roles_mapper_ids: "{{ grp_mapper_ids_assert }}"
groups_path: "{{ desired_groups_path_assert }}"
top_group: "{{ desired_groups_top_assert }}"