community.general icon indicating copy to clipboard operation
community.general copied to clipboard

keycloak_user_federation duplicate mapper name

Open fragfutter opened this issue 1 year ago • 2 comments

Summary

Creating an ldap user federation can't be run twice.

Issue Type

Bug Report

Component Name

keycloak_user_federation

Ansible Version

ansible [core 2.13.3]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/handel/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.10/site-packages/ansible
  ansible collection location = /home/handel/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.6 (main, Aug  3 2022, 17:39:45) [GCC 12.1.1 20220730]
  jinja version = 3.1.2
  libyaml = True

Community.general Version

# /usr/lib/python3.10/site-packages/ansible_collections
Collection        Version
----------------- -------
community.general 5.5.0 

Configuration

OS / Environment

archlinux

keycloak 18.0.2

Steps to Reproduce

the playbook task

- name: ldap
  tags:
  - ldap
  community.general.keycloak_user_federation:
    name: "{{ keycloak.default_realm }}"
    auth_client_id: "{{ keycloak.auth_client_id }}"
    auth_keycloak_url: "{{ keycloak.auth_keycloak_url }}"
    auth_realm: "{{ keycloak.auth_realm }}"
    auth_username: "{{ keycloak.auth_username }}"
    auth_password: "{{ keycloak.auth_password }}"
    realm: "{{ keycloak.default_realm }}"
    provider_id: ldap
    provider_type: org.keycloak.storage.UserStorageProvider
    config:
      # connection
      vendor: ad
      connectionUrl: "{{ ldap.connectionUrl }}"
      authType: simple
      bindDn: "{{ ldap.bindDn }}"
      bindCredential: "{{ ldap.bindCredential }}"
      batchSizeForSync: 500
      pagination: true
      # search users
      userObjectClasses: person, organizationalPerson, user
      usersDn: "{{ ldap.user_base }}"
      searchScope: 2
      # attributes
      uuidLDAPAttribute: objectGUID
      usernameLDAPAttribute: uid
      rdnLDAPAttribute: cn
      # settings
      editMode: READ_ONLY
      validatePasswordPolicy: false
      trustEmail: "true"
      importEnabled: true
      syncRegistrations: false
      usePasswordModifyExtendedOp: "false"
    mappers:
      - name: "username"
        providerId: "user-attribute-ldap-mapper"
        providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper"
        config:
          always.read.value.from.ldap: "false"
          is.mandatory.in.ldap: "true"
          ldap.attribute: "uid"
          read.only: "true"
          user.model.attribute: "username"

on the first run it will create the federation, on the second run it will fail with

Expected Results

ansible creates the federation on the first run, won't change anything on the second run

Actual Results

second run fails

fatal: [host]: FAILED! => {"changed": false, "msg": "Found multiple mappers with name `username`. Cannot continue."}

with a bit of debug output in keycloak_user_federation.py, here is what was found

FAILED! => {
"changed": false, 
"msg": "Found multiple mappers with name `
[
{'id': 'b2267b7f-063b-4046-ae5d-94cc36c4218b', 'name': 'username', 
'providerId': 'user-attribute-ldap-mapper', 'providerType': 'org.keycloak.storage.ldap.mappers.LDAPStorageMapper', 
'parentId': '3a6b1799-3dd7-416f-ab99-c5cc256a9581', 
'config': {'ldap.attribute': ['uid'], 'is.mandatory.in.ldap': ['true'], 'always.read.value.from.ldap': ['false'], 'read.only': ['true'], 'user.model.attribute': ['username']}}, 

{'id': '6e952bf9-4df1-49ee-8e46-5386d94cb716', 'name': 'username', 
'providerId': 'user-attribute-ldap-mapper', 'providerType': 'org.keycloak.storage.ldap.mappers.LDAPStorageMapper', 
'parentId': '3a6b1799-3dd7-416f-ab99-c5cc256a9581', 
'config': {'ldap.attribute': ['uid'], 'is.mandatory.in.ldap': ['true'], 'read.only': ['true'], 'always.read.value.from.ldap': ['false'], 'user.model.attribute': ['username']}}]`. 

Cannot continue."}

i assume keycloak will create a default mapper (with a random id) during creation. Ansible has the mappings cached (before the creation of the federation, in other words no mapping) and adds a second mapping (also with a random id).

Code of Conduct

  • [X] I agree to follow the Ansible Code of Conduct

fragfutter avatar Sep 15 '22 10:09 fragfutter

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot avatar Sep 15 '22 10:09 ansibullbot

cc @eikef @laurpaum @ndclt click here for bot help

ansibullbot avatar Sep 15 '22 10:09 ansibullbot