mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
[PR #7881/001292c7 backport][stable-8] Fixes #1226 - keycloak_client detects changes on check_mode but not in run mode (#7979)
Fixes #1226 - keycloak_client detects changes on check_mode but not in run mode (#7881)
* Fix warning integrated
* Update Keycloak version intergrated test
* Exclude metadata from diff test
* Sanity
* Add fragments
* typo
* Add test
* Update changelogs/fragments/7881-fix-keycloak-client-ckeckmode.yml
Co-authored-by: Felix Fontein <felix@fontein.de>
* Remove docker compose
* Update changelogs/fragments/7881-fix-keycloak-client-ckeckmode.yml
Co-authored-by: Felix Fontein <felix@fontein.de>
---------
Co-authored-by: Andre Desrosiers <andre.desrosiers@ssss.gouv.qc.ca>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 001292c780
)
Co-authored-by: desand01 <desrosiers.a@hotmail.com>
This commit is contained in:
parent
01d3a106ac
commit
8eec4767bd
6 changed files with 98 additions and 82 deletions
|
@ -0,0 +1,2 @@
|
||||||
|
bugfixes:
|
||||||
|
- keycloak_client - fixes issue when metadata is provided in desired state when task is in check mode (https://github.com/ansible-collections/community.general/issues/1226, https://github.com/ansible-collections/community.general/pull/7881).
|
|
@ -717,13 +717,14 @@ end_state:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import KeycloakAPI, camel, \
|
from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import KeycloakAPI, camel, \
|
||||||
keycloak_argument_spec, get_token, KeycloakError
|
keycloak_argument_spec, get_token, KeycloakError, is_struct_included
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
|
||||||
PROTOCOL_OPENID_CONNECT = 'openid-connect'
|
PROTOCOL_OPENID_CONNECT = 'openid-connect'
|
||||||
PROTOCOL_SAML = 'saml'
|
PROTOCOL_SAML = 'saml'
|
||||||
|
CLIENT_META_DATA = ['authorizationServicesEnabled']
|
||||||
|
|
||||||
|
|
||||||
def normalise_cr(clientrep, remove_ids=False):
|
def normalise_cr(clientrep, remove_ids=False):
|
||||||
|
@ -946,7 +947,7 @@ def main():
|
||||||
if module._diff:
|
if module._diff:
|
||||||
result['diff'] = dict(before=sanitize_cr(before_norm),
|
result['diff'] = dict(before=sanitize_cr(before_norm),
|
||||||
after=sanitize_cr(desired_norm))
|
after=sanitize_cr(desired_norm))
|
||||||
result['changed'] = (before_norm != desired_norm)
|
result['changed'] = not is_struct_included(desired_norm, before_norm, CLIENT_META_DATA)
|
||||||
|
|
||||||
module.exit_json(**result)
|
module.exit_json(**result)
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,16 @@ GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://w
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
-->
|
-->
|
||||||
|
|
||||||
The integration test can be performed as follows:
|
# Running keycloak_client module integration test
|
||||||
|
|
||||||
```
|
To run Keycloak client module's integration test, start a keycloak server using Docker:
|
||||||
# 1. Start docker-compose:
|
|
||||||
docker-compose -f tests/integration/targets/keycloak_client/docker-compose.yml stop
|
|
||||||
docker-compose -f tests/integration/targets/keycloak_client/docker-compose.yml rm -f -v
|
|
||||||
docker-compose -f tests/integration/targets/keycloak_client/docker-compose.yml up -d
|
|
||||||
|
|
||||||
# 2. Run the integration tests:
|
docker run -d --rm --name mykeycloak -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=password quay.io/keycloak/keycloak:latest start-dev --http-relative-path /auth
|
||||||
ansible-test integration keycloak_client --allow-unsupported -v
|
|
||||||
```
|
Run the integration tests:
|
||||||
|
|
||||||
|
ansible-test integration -v keycloak_client --allow-unsupported --docker fedora35 --docker-network host
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
|
||||||
|
docker stop mykeycloak
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
---
|
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
version: '3.4'
|
|
||||||
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres:9.6
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: postgres
|
|
||||||
POSTGRES_DB: postgres
|
|
||||||
POSTGRES_PASSWORD: postgres
|
|
||||||
|
|
||||||
keycloak:
|
|
||||||
image: jboss/keycloak:12.0.4
|
|
||||||
ports:
|
|
||||||
- 8080:8080
|
|
||||||
|
|
||||||
environment:
|
|
||||||
DB_VENDOR: postgres
|
|
||||||
DB_ADDR: postgres
|
|
||||||
DB_DATABASE: postgres
|
|
||||||
DB_USER: postgres
|
|
||||||
DB_SCHEMA: public
|
|
||||||
DB_PASSWORD: postgres
|
|
||||||
|
|
||||||
KEYCLOAK_USER: admin
|
|
||||||
KEYCLOAK_PASSWORD: password
|
|
|
@ -2,27 +2,42 @@
|
||||||
# Copyright (c) Ansible Project
|
# Copyright (c) Ansible Project
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
- name: Wait for Keycloak
|
||||||
|
uri:
|
||||||
|
url: "{{ url }}/admin/"
|
||||||
|
status_code: 200
|
||||||
|
validate_certs: no
|
||||||
|
register: result
|
||||||
|
until: result.status == 200
|
||||||
|
retries: 10
|
||||||
|
delay: 10
|
||||||
|
|
||||||
- name: Delete realm
|
- name: Delete realm
|
||||||
community.general.keycloak_realm: "{{ auth_args | combine(call_args) }}"
|
community.general.keycloak_realm:
|
||||||
vars:
|
auth_keycloak_url: "{{ url }}"
|
||||||
call_args:
|
auth_realm: "{{ admin_realm }}"
|
||||||
|
auth_username: "{{ admin_user }}"
|
||||||
|
auth_password: "{{ admin_password }}"
|
||||||
id: "{{ realm }}"
|
id: "{{ realm }}"
|
||||||
realm: "{{ realm }}"
|
realm: "{{ realm }}"
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Create realm
|
- name: Create realm
|
||||||
community.general.keycloak_realm: "{{ auth_args | combine(call_args) }}"
|
community.general.keycloak_realm:
|
||||||
vars:
|
auth_keycloak_url: "{{ url }}"
|
||||||
call_args:
|
auth_realm: "{{ admin_realm }}"
|
||||||
|
auth_username: "{{ admin_user }}"
|
||||||
|
auth_password: "{{ admin_password }}"
|
||||||
id: "{{ realm }}"
|
id: "{{ realm }}"
|
||||||
realm: "{{ realm }}"
|
realm: "{{ realm }}"
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Desire client
|
- name: Desire client
|
||||||
community.general.keycloak_client: "{{ auth_args | combine(call_args) }}"
|
community.general.keycloak_client:
|
||||||
vars:
|
auth_keycloak_url: "{{ url }}"
|
||||||
call_args:
|
auth_realm: "{{ admin_realm }}"
|
||||||
|
auth_username: "{{ admin_user }}"
|
||||||
|
auth_password: "{{ admin_password }}"
|
||||||
realm: "{{ realm }}"
|
realm: "{{ realm }}"
|
||||||
client_id: "{{ client_id }}"
|
client_id: "{{ client_id }}"
|
||||||
state: present
|
state: present
|
||||||
|
@ -32,9 +47,11 @@
|
||||||
register: desire_client_not_present
|
register: desire_client_not_present
|
||||||
|
|
||||||
- name: Desire client again with same props
|
- name: Desire client again with same props
|
||||||
community.general.keycloak_client: "{{ auth_args | combine(call_args) }}"
|
community.general.keycloak_client:
|
||||||
vars:
|
auth_keycloak_url: "{{ url }}"
|
||||||
call_args:
|
auth_realm: "{{ admin_realm }}"
|
||||||
|
auth_username: "{{ admin_user }}"
|
||||||
|
auth_password: "{{ admin_password }}"
|
||||||
realm: "{{ realm }}"
|
realm: "{{ realm }}"
|
||||||
client_id: "{{ client_id }}"
|
client_id: "{{ client_id }}"
|
||||||
state: present
|
state: present
|
||||||
|
@ -44,16 +61,19 @@
|
||||||
register: desire_client_when_present_and_same
|
register: desire_client_when_present_and_same
|
||||||
|
|
||||||
- name: Check client again with same props
|
- name: Check client again with same props
|
||||||
community.general.keycloak_client: "{{ auth_args | combine(call_args) }}"
|
community.general.keycloak_client:
|
||||||
check_mode: true
|
auth_keycloak_url: "{{ url }}"
|
||||||
vars:
|
auth_realm: "{{ admin_realm }}"
|
||||||
call_args:
|
auth_username: "{{ admin_user }}"
|
||||||
|
auth_password: "{{ admin_password }}"
|
||||||
realm: "{{ realm }}"
|
realm: "{{ realm }}"
|
||||||
client_id: "{{ client_id }}"
|
client_id: "{{ client_id }}"
|
||||||
state: present
|
state: present
|
||||||
redirect_uris: '{{redirect_uris1}}'
|
redirect_uris: '{{redirect_uris1}}'
|
||||||
attributes: '{{client_attributes1}}'
|
attributes: '{{client_attributes1}}'
|
||||||
protocol_mappers: '{{protocol_mappers1}}'
|
protocol_mappers: '{{protocol_mappers1}}'
|
||||||
|
authorization_services_enabled: False
|
||||||
|
check_mode: true
|
||||||
register: check_client_when_present_and_same
|
register: check_client_when_present_and_same
|
||||||
|
|
||||||
- name: Assert changes not detected in last two tasks (desire when same, and check)
|
- name: Assert changes not detected in last two tasks (desire when same, and check)
|
||||||
|
@ -61,3 +81,25 @@
|
||||||
that:
|
that:
|
||||||
- desire_client_when_present_and_same is not changed
|
- desire_client_when_present_and_same is not changed
|
||||||
- check_client_when_present_and_same is not changed
|
- check_client_when_present_and_same is not changed
|
||||||
|
|
||||||
|
- name: Check client again with changed props
|
||||||
|
community.general.keycloak_client:
|
||||||
|
auth_keycloak_url: "{{ url }}"
|
||||||
|
auth_realm: "{{ admin_realm }}"
|
||||||
|
auth_username: "{{ admin_user }}"
|
||||||
|
auth_password: "{{ admin_password }}"
|
||||||
|
realm: "{{ realm }}"
|
||||||
|
client_id: "{{ client_id }}"
|
||||||
|
state: present
|
||||||
|
redirect_uris: '{{redirect_uris1}}'
|
||||||
|
attributes: '{{client_attributes1}}'
|
||||||
|
protocol_mappers: '{{protocol_mappers1}}'
|
||||||
|
authorization_services_enabled: False
|
||||||
|
service_accounts_enabled: True
|
||||||
|
check_mode: true
|
||||||
|
register: check_client_when_present_and_changed
|
||||||
|
|
||||||
|
- name: Assert changes detected in last tasks
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- check_client_when_present_and_changed is changed
|
||||||
|
|
|
@ -24,7 +24,7 @@ redirect_uris1:
|
||||||
- "http://example.b.com/"
|
- "http://example.b.com/"
|
||||||
- "http://example.a.com/"
|
- "http://example.a.com/"
|
||||||
|
|
||||||
client_attributes1: {"backchannel.logout.session.required": true, "backchannel.logout.revoke.offline.tokens": false}
|
client_attributes1: {"backchannel.logout.session.required": true, "backchannel.logout.revoke.offline.tokens": false, "client.secret.creation.time": 0}
|
||||||
|
|
||||||
protocol_mappers1:
|
protocol_mappers1:
|
||||||
- name: 'email'
|
- name: 'email'
|
||||||
|
|
Loading…
Reference in a new issue