ansible-collections / community.general

Ansible Community General Collection
https://galaxy.ansible.com/ui/repo/published/community/general/
GNU General Public License v3.0
816 stars 1.49k forks source link

keycloak_realm: Keycloak realm creation fail with HTTP Error 500 #4224

Open bagasse opened 2 years ago

bagasse commented 2 years ago

Summary

Using provided example in documentation for community.general.keycloak_realm fail

Issue Type

Bug Report

Component Name

community.general.keycloak_realm

Ansible Version

$ ansible --version
ansible [core 2.12.1]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.10/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.0 (default, Oct  4 2021, 00:00:00) [GCC 11.2.1 20210728 (Red Hat 11.2.1-1)]
  jinja version = 3.0.1
  libyaml = True

Community.general Version

$ ansible-galaxy collection list community.general

# /root/.ansible/collections/ansible_collections
Collection        Version
----------------- -------
community.general 4.4.0

Configuration

$ ansible-config dump --only-changed
GALAXY_SERVER_LIST(/etc/ansible/ansible.cfg) = ['automation_hub', 'galaxy']

OS / Environment

Fedora 35 (client) Keycloak server: keycloak-server-15.0.4-1 on EL8

Steps to Reproduce

- name: Create or update keycloak realm
  community.general.keycloak_realm:
    auth_client_id: admin-cli
    auth_keycloak_url: https://{{ keycloak_server  }}:8443/auth
    auth_realm: master
    auth_username: "{{ keycloak_user }}"
    auth_password: "{{ keycloak_password }}"
    id: test
    state: present

Expected Results

Realm created in keycloak

Actual Results

TASK [../roles/rh_sso_custom : Create or update keycloak realm] *****************************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: urllib.error.HTTPError: HTTP Error 500: Internal Server Error                                                     
fatal: [sso]: FAILED! => {"changed": false, "msg": "Could not create realm test: HTTP Error 500: Internal Server Error"}
2022-02-18 04:09:01,586 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-1) Uncaught server error: java.lang.NullPointerException
    at org.keycloak.services.managers.RealmManager.determineDefaultRoleName(RealmManager.java:610)
    at org.keycloak.services.managers.RealmManager.importRealm(RealmManager.java:518)
    at org.keycloak.services.managers.RealmManager.importRealm(RealmManager.java:495)
    at org.keycloak.services.resources.admin.RealmsAdminResource.importRealm(RealmsAdminResource.java:131)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:138)
    at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:546)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:435)
    at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:396)
    at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:398)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:365)
    at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:150)
    at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:104)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:440)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:229)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:135)
    at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358)
    at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:138)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:215)
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:245)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:61)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
    at org.keycloak.provider.wildfly.WildFlyRequestFilter.lambda$doFilter$0(WildFlyRequestFilter.java:41)
    at org.keycloak.services.filters.AbstractRequestFilter.filter(AbstractRequestFilter.java:43)
    at org.keycloak.provider.wildfly.WildFlyRequestFilter.doFilter(WildFlyRequestFilter.java:39)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
    at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
    at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
    at io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:280)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:79)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:134)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:131)
    at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
    at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1530)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:260)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:79)
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:100)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:387)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:852)
    at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
    at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1280)
    at java.lang.Thread.run(Thread.java:750)

Code of Conduct

ansibullbot commented 2 years ago

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 commented 2 years ago

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

kris2kris commented 2 years ago

@bagasse maybe something becomes mandatory with an update of keycloak... Did you try to add the property realm ?

bagasse commented 2 years ago

Yes @kris2kris , thanks for the pointer, adding realm make it works !

eg:

- name: Create or update keycloak realm
  community.general.keycloak_realm:
    auth_client_id: admin-cli
    auth_keycloak_url: https://{{ keycloak_server  }}:8443/auth
    auth_realm: master
    auth_username: "{{ keycloak_user }}"
    auth_password: "{{ keycloak_password }}"
    id: test
    realm: test
    state: present
vicentini commented 2 years ago

If you define an 'id' different than 'realm', the realm gets created, but the ansible task returns with a python error.

The full traceback is:
Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-tmp-1647348149.4734232-9918-271171871220015/AnsiballZ_keycloak_realm.py", line 107, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-tmp-1647348149.4734232-9918-271171871220015/AnsiballZ_keycloak_realm.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-tmp-1647348149.4734232-9918-271171871220015/AnsiballZ_keycloak_realm.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.community.general.plugins.modules.keycloak_realm', init_globals=dict(_module_fqn='ansible_collections.community.general.plugins.modules.keycloak_realm', _modlib_path=modlib_path),
  File "/usr/lib/python3.10/runpy.py", line 209, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib/python3.10/runpy.py", line 96, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_community.general.keycloak_realm_payload_5kwk2cri/ansible_community.general.keycloak_realm_payload.zip/ansible_collections/community/general/plugins/modules/keycloak_realm.py", line 819, in <module>
  File "/tmp/ansible_community.general.keycloak_realm_payload_5kwk2cri/ansible_community.general.keycloak_realm_payload.zip/ansible_collections/community/general/plugins/modules/keycloak_realm.py", line 760, in main
  File "/tmp/ansible_community.general.keycloak_realm_payload_5kwk2cri/ansible_community.general.keycloak_realm_payload.zip/ansible_collections/community/general/plugins/modules/keycloak_realm.py", line 584, in sanitize_cr
AttributeError: 'NoneType' object has no attribute 'copy'
fatal: [localhost]: FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3.10"
    },
    "changed": false,
    "module_stderr": "<same-traceback-as-above>",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

I don't know, if both id and realm name need to be the same, but everywhere else in keycloak an id is a generated uuid.

kris2kris commented 2 years ago

If you define an 'id' different than 'realm', the realm gets created, but the ansible task returns with a python error.

The full traceback is:
Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-tmp-1647348149.4734232-9918-271171871220015/AnsiballZ_keycloak_realm.py", line 107, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-tmp-1647348149.4734232-9918-271171871220015/AnsiballZ_keycloak_realm.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-tmp-1647348149.4734232-9918-271171871220015/AnsiballZ_keycloak_realm.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.community.general.plugins.modules.keycloak_realm', init_globals=dict(_module_fqn='ansible_collections.community.general.plugins.modules.keycloak_realm', _modlib_path=modlib_path),
  File "/usr/lib/python3.10/runpy.py", line 209, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib/python3.10/runpy.py", line 96, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_community.general.keycloak_realm_payload_5kwk2cri/ansible_community.general.keycloak_realm_payload.zip/ansible_collections/community/general/plugins/modules/keycloak_realm.py", line 819, in <module>
  File "/tmp/ansible_community.general.keycloak_realm_payload_5kwk2cri/ansible_community.general.keycloak_realm_payload.zip/ansible_collections/community/general/plugins/modules/keycloak_realm.py", line 760, in main
  File "/tmp/ansible_community.general.keycloak_realm_payload_5kwk2cri/ansible_community.general.keycloak_realm_payload.zip/ansible_collections/community/general/plugins/modules/keycloak_realm.py", line 584, in sanitize_cr
AttributeError: 'NoneType' object has no attribute 'copy'
fatal: [localhost]: FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3.10"
    },
    "changed": false,
    "module_stderr": "<same-traceback-as-above>",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

I don't know, if both id and realm name need to be the same, but everywhere else in keycloak an id is a generated uuid.

I can be wrong but I think realm ID is not a UUID when using keycloak frontend but is equal to realm name

mattgagliardi commented 1 year ago

@kris2kris you're correct, by default when created via the CLI (kcadm) the realm name and realm id are different. The name is whatever value you attach to the "realm" key and the "id" key is populated with a GUID value...if you don't specify the value for the id key (as in you don't include it in the CLI call). If you include the id and specify a value it is accepted. If you create the realm via the GUI whatever name you give the realm is also the value for the id key.

It would be terrific if we could get the documentation updated to reflect that the "realm" key/attribute must be included as part of the Ansible configuration to create a realm. The examples show the "id" key/attribute in place, but with only that realm creation...at least in 18.0.1...fails with the previously-listed error(s). As soon as I add the "realm" key/attribute it works fine. If I leave out the id key/attribute the Ansible call fails BTW (whereas with the straight CLI the realm would be created but with a GUID value in the id key).

ansibullbot commented 1 year ago

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 commented 1 year ago

cc @mattock click here for bot help

ansibullbot commented 1 month ago

cc @thomasbach-dev click here for bot help