diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index c8e19d0b13..18f4f66e1f 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -281,6 +281,8 @@ files: maintainers: $team_huawei $module_utils/identity/keycloak/keycloak.py: maintainers: $team_keycloak + $module_utils/identity/keycloak/keycloak_clientsecret.py: + maintainers: $team_keycloak fynncfchen johncant $module_utils/ipa.py: labels: ipa maintainers: $team_ipa @@ -668,6 +670,10 @@ files: maintainers: Gaetan2907 $modules/keycloak_clientscope.py: maintainers: Gaetan2907 + $modules/keycloak_clientsecret_info.py: + maintainers: fynncfchen johncant + $modules/keycloak_clientsecret_regenerate.py: + maintainers: fynncfchen johncant $modules/keycloak_group.py: maintainers: adamgoossens $modules/keycloak_identity_provider.py: diff --git a/plugins/module_utils/identity/keycloak/keycloak.py b/plugins/module_utils/identity/keycloak/keycloak.py index 078925ef71..87b2120318 100644 --- a/plugins/module_utils/identity/keycloak/keycloak.py +++ b/plugins/module_utils/identity/keycloak/keycloak.py @@ -58,6 +58,8 @@ URL_CLIENT_USER_ROLEMAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappi URL_CLIENT_USER_ROLEMAPPINGS_AVAILABLE = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client}/available" URL_CLIENT_USER_ROLEMAPPINGS_COMPOSITE = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client}/composite" +URL_CLIENTSECRET = "{url}/admin/realms/{realm}/clients/{id}/client-secret" + URL_AUTHENTICATION_FLOWS = "{url}/admin/realms/{realm}/authentication/flows" URL_AUTHENTICATION_FLOW = "{url}/admin/realms/{realm}/authentication/flows/{id}" URL_AUTHENTICATION_FLOW_COPY = "{url}/admin/realms/{realm}/authentication/flows/{copyfrom}/copy" @@ -1160,6 +1162,52 @@ class KeycloakAPI(object): self.module.fail_json(msg='Could not update protocolmappers for clientscope %s in realm %s: %s' % (mapper_rep, realm, str(e))) + def create_clientsecret(self, id, realm="master"): + """ Generate a new client secret by id + + :param id: id (not clientId) of client to be queried + :param realm: client from this realm + :return: dict of credential representation + """ + clientsecret_url = URL_CLIENTSECRET.format(url=self.baseurl, realm=realm, id=id) + + try: + return json.loads(to_native(open_url(clientsecret_url, method='POST', headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s' + % (id, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s' + % (id, realm, str(e))) + + def get_clientsecret(self, id, realm="master"): + """ Obtain client secret by id + + :param id: id (not clientId) of client to be queried + :param realm: client from this realm + :return: dict of credential representation + """ + clientsecret_url = URL_CLIENTSECRET.format(url=self.baseurl, realm=realm, id=id) + + try: + return json.loads(to_native(open_url(clientsecret_url, method='GET', headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s' + % (id, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s' + % (id, realm, str(e))) + def get_groups(self, realm="master"): """ Fetch the name and ID of all groups on the Keycloak server. diff --git a/plugins/module_utils/identity/keycloak/keycloak_clientsecret.py b/plugins/module_utils/identity/keycloak/keycloak_clientsecret.py new file mode 100644 index 0000000000..85caa8e16b --- /dev/null +++ b/plugins/module_utils/identity/keycloak/keycloak_clientsecret.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2022, John Cant +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import \ + keycloak_argument_spec + + +def keycloak_clientsecret_module(): + """ + Returns an AnsibleModule definition for modules that interact with a client + secret. + + :return: argument_spec dict + """ + argument_spec = keycloak_argument_spec() + + meta_args = dict( + realm=dict(default='master'), + id=dict(type='str'), + client_id=dict(type='str', aliases=['clientId']), + ) + + argument_spec.update(meta_args) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_one_of=([['id', 'client_id'], + ['token', 'auth_realm', 'auth_username', 'auth_password']]), + required_together=([['auth_realm', 'auth_username', 'auth_password']]), + mutually_exclusive=[ + ['token', 'auth_realm'], + ['token', 'auth_username'], + ['token', 'auth_password'] + ]) + + return module + + +def keycloak_clientsecret_module_resolve_params(module, kc): + """ + Given an AnsibleModule definition for keycloak_clientsecret_*, and a + KeycloakAPI client, resolve the params needed to interact with the Keycloak + client secret, looking up the client by clientId if necessary via an API + call. + + :return: tuple of id, realm + """ + + realm = module.params.get('realm') + id = module.params.get('id') + client_id = module.params.get('client_id') + + # only lookup the client_id if id isn't provided. + # in the case that both are provided, prefer the ID, since it's one + # less lookup. + if id is None: + # Due to the required_one_of spec, client_id is guaranteed to not be None + client = kc.get_client_by_clientid(client_id, realm=realm) + + if client is None: + module.fail_json( + msg='Client does not exist {client_id}'.format(client_id=client_id) + ) + + id = client['id'] + + return id, realm diff --git a/plugins/modules/keycloak_clientsecret_info.py b/plugins/modules/keycloak_clientsecret_info.py new file mode 100644 index 0000000000..98a41ad20a --- /dev/null +++ b/plugins/modules/keycloak_clientsecret_info.py @@ -0,0 +1,161 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2022, Fynn Chen +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: keycloak_clientsecret_info + +short_description: Retrieve client secret via Keycloak API + +version_added: 6.1.0 + +description: + - This module allows you to get a Keycloak client secret via the Keycloak + REST API. It requires access to the REST API via OpenID Connect; the user + connecting and the client being used must have the requisite access rights. + In a default Keycloak installation, admin-cli and an admin user would work, + as would a separate client definition with the scope tailored to your needs + and a user having the expected roles. + + - When retrieving a new client secret, where possible provide the client's + I(id) (not I(client_id)) to the module. This removes a lookup to the API to + translate the I(client_id) into the client ID. + + - "Note that this module returns the client secret. To avoid this showing up in the logs, + please add C(no_log: true) to the task." + +options: + realm: + type: str + description: + - They Keycloak realm under which this client resides. + default: 'master' + + id: + description: + - The unique identifier for this client. + - This parameter is not required for getting or generating a client secret but + providing it will reduce the number of API calls required. + type: str + + client_id: + description: + - The I(client_id) of the client. Passing this instead of I(id) results in an + extra API call. + aliases: + - clientId + type: str + + +extends_documentation_fragment: + - community.general.keycloak + - community.general.attributes + - community.general.attributes.info_module + +author: + - Fynn Chen (@fynncfchen) + - John Cant (@johncant) +''' + +EXAMPLES = ''' +- name: Get a Keycloak client secret, authentication with credentials + community.general.keycloak_clientsecret_info: + id: '9d59aa76-2755-48c6-b1af-beb70a82c3cd' + realm: MyCustomRealm + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + delegate_to: localhost + no_log: true + +- name: Get a new Keycloak client secret, authentication with token + community.general.keycloak_clientsecret_info: + id: '9d59aa76-2755-48c6-b1af-beb70a82c3cd' + realm: MyCustomRealm + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + token: TOKEN + delegate_to: localhost + no_log: true + +- name: Get a new Keycloak client secret, passing client_id instead of id + community.general.keycloak_clientsecret_info: + client_id: 'myClientId' + realm: MyCustomRealm + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + token: TOKEN + delegate_to: localhost + no_log: true +''' + +RETURN = ''' +msg: + description: Textual description of whether we succeeded or failed + returned: always + type: str + +clientsecret_info: + description: Representation of the client secret + returned: on success + type: complex + contains: + type: + description: Credential type. + type: str + returned: always + sample: secret + value: + description: Client secret. + type: str + returned: always + sample: cUGnX1EIeTtPPAkcyGMv0ncyqDPu68P1 +''' + +from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import ( + KeycloakAPI, KeycloakError, get_token) +from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak_clientsecret import ( + keycloak_clientsecret_module, keycloak_clientsecret_module_resolve_params) + + +def main(): + """ + Module keycloak_clientsecret_info + + :return: + """ + + module = keycloak_clientsecret_module() + + # Obtain access token, initialize API + try: + connection_header = get_token(module.params) + except KeycloakError as e: + module.fail_json(msg=str(e)) + + kc = KeycloakAPI(module, connection_header) + + id, realm = keycloak_clientsecret_module_resolve_params(module, kc) + + clientsecret = kc.get_clientsecret(id=id, realm=realm) + + result = { + 'clientsecret_info': clientsecret, + 'msg': 'Get client secret successful for ID {id}'.format(id=id) + } + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/keycloak_clientsecret_regenerate.py b/plugins/modules/keycloak_clientsecret_regenerate.py new file mode 100644 index 0000000000..7a48a25d25 --- /dev/null +++ b/plugins/modules/keycloak_clientsecret_regenerate.py @@ -0,0 +1,167 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2022, Fynn Chen +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: keycloak_clientsecret_regenerate + +short_description: Regenerate Keycloak client secret via Keycloak API + +version_added: 6.1.0 + +description: + - This module allows you to regenerate a Keycloak client secret via the + Keycloak REST API. It requires access to the REST API via OpenID Connect; + the user connecting and the client being used must have the requisite access + rights. In a default Keycloak installation, admin-cli and an admin user + would work, as would a separate client definition with the scope tailored to + your needs and a user having the expected roles. + + - When regenerating a client secret, where possible provide the client's id + (not client_id) to the module. This removes a lookup to the API to + translate the client_id into the client ID. + + - "Note that this module returns the client secret. To avoid this showing up in the logs, + please add C(no_log: true) to the task." + +options: + realm: + type: str + description: + - They Keycloak realm under which this client resides. + default: 'master' + + id: + description: + - The unique identifier for this client. + - This parameter is not required for getting or generating a client secret but + providing it will reduce the number of API calls required. + type: str + + client_id: + description: + - The client_id of the client. Passing this instead of id results in an + extra API call. + aliases: + - clientId + type: str + + +extends_documentation_fragment: + - community.general.keycloak + +author: + - Fynn Chen (@fynncfchen) + - John Cant (@johncant) +''' + +EXAMPLES = ''' +- name: Regenerate a Keycloak client secret, authentication with credentials + community.general.keycloak_clientsecret_regenerate: + id: '9d59aa76-2755-48c6-b1af-beb70a82c3cd' + realm: MyCustomRealm + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + delegate_to: localhost + no_log: true + +- name: Regenerate a Keycloak client secret, authentication with token + community.general.keycloak_clientsecret_regenerate: + id: '9d59aa76-2755-48c6-b1af-beb70a82c3cd' + realm: MyCustomRealm + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + token: TOKEN + delegate_to: localhost + no_log: true + +- name: Regenerate a Keycloak client secret, passing client_id instead of id + community.general.keycloak_clientsecret_info: + client_id: 'myClientId' + realm: MyCustomRealm + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + token: TOKEN + delegate_to: localhost + no_log: true +''' + +RETURN = ''' +msg: + description: Message as to what action was taken. + returned: always + type: str + +end_state: + description: Representation of the client credential after module execution + returned: on success + type: complex + contains: + type: + description: Credential type. + type: str + returned: always + sample: secret + value: + description: Client secret. + type: str + returned: always + sample: cUGnX1EIeTtPPAkcyGMv0ncyqDPu68P1 + +''' + +from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import ( + KeycloakAPI, KeycloakError, get_token) +from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak_clientsecret import ( + keycloak_clientsecret_module, keycloak_clientsecret_module_resolve_params) + + +def main(): + """ + Module keycloak_clientsecret_regenerate + + :return: + """ + + module = keycloak_clientsecret_module() + + # Obtain access token, initialize API + try: + connection_header = get_token(module.params) + except KeycloakError as e: + module.fail_json(msg=str(e)) + + kc = KeycloakAPI(module, connection_header) + + id, realm = keycloak_clientsecret_module_resolve_params(module, kc) + + if module.check_mode: + dummy_result = { + "msg": 'No action taken while in check mode', + "end_state": {'type': 'secret', 'value': 'X' * 32} + } + module.exit_json(**dummy_result) + + # Create new secret + clientsecret = kc.create_clientsecret(id=id, realm=realm) + + result = { + "msg": 'New client secret has been generated for ID {id}'.format(id=id), + "end_state": clientsecret + } + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/tests/integration/targets/keycloak_clientsecret_info/README.md b/tests/integration/targets/keycloak_clientsecret_info/README.md new file mode 100644 index 0000000000..fb721801da --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_info/README.md @@ -0,0 +1,17 @@ + + +The integration test can be performed as follows: + +``` +# 1. Start docker-compose: +docker-compose -f tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml stop +docker-compose -f tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml rm -f -v +docker-compose -f tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml up -d + +# 2. Run the integration tests: +ansible-test integration keycloak_clientsecret_info --allow-unsupported -v +``` diff --git a/tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml b/tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml new file mode 100644 index 0000000000..5e14e9aac1 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml @@ -0,0 +1,31 @@ +--- +# 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 diff --git a/tests/integration/targets/keycloak_clientsecret_info/tasks/main.yml b/tests/integration/targets/keycloak_clientsecret_info/tasks/main.yml new file mode 100644 index 0000000000..a0cacf1889 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_info/tasks/main.yml @@ -0,0 +1,48 @@ +--- +# 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 + +- name: Create realm + community.general.keycloak_realm: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + id: "{{ realm }}" + realm: "{{ realm }}" + state: present + +- name: Keycloak Client + community.general.keycloak_client: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + realm: "{{ realm }}" + client_id: "{{ client_id }}" + state: present + register: client + +- name: Keycloak Client fetch clientsecret by client_id + community.general.keycloak_clientsecret_info: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + realm: "{{ realm }}" + client_id: "{{ client_id }}" + register: fetch_by_client_id_result + +- name: Assert that the client secret was retrieved + assert: + that: + - fetch_by_client_id_result.clientsecret_info.type == "secret" + - "{{ fetch_by_client_id_result.clientsecret_info.value | length }} >= 32" + +- name: Keycloak Client fetch clientsecret by id + community.general.keycloak_clientsecret_info: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + realm: "{{ realm }}" + id: "{{ client.end_state.id }}" + register: fetch_by_id_result + +- name: Assert that the same client secret was retrieved both times + assert: + that: + - fetch_by_id_result.clientsecret_info.value == fetch_by_client_id_result.clientsecret_info.value diff --git a/tests/integration/targets/keycloak_clientsecret_info/vars/main.yml b/tests/integration/targets/keycloak_clientsecret_info/vars/main.yml new file mode 100644 index 0000000000..8c913705f7 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_info/vars/main.yml @@ -0,0 +1,20 @@ +--- +# 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 + +url: http://localhost:8080/auth +admin_realm: master +admin_user: admin +admin_password: password +realm: myrealm +client_id: myclient +role: myrole +description_1: desc 1 +description_2: desc 2 + +auth_args: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" diff --git a/tests/integration/targets/keycloak_clientsecret_regenerate/README.md b/tests/integration/targets/keycloak_clientsecret_regenerate/README.md new file mode 100644 index 0000000000..08251b4c52 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_regenerate/README.md @@ -0,0 +1,17 @@ + + +The integration test can be performed as follows: + +``` +# 1. Start docker-compose: +docker-compose -f tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml stop +docker-compose -f tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml rm -f -v +docker-compose -f tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml up -d + +# 2. Run the integration tests: +ansible-test integration keycloak_clientsecret_regenerate --allow-unsupported -v +``` diff --git a/tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml b/tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml new file mode 100644 index 0000000000..5e14e9aac1 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml @@ -0,0 +1,31 @@ +--- +# 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 diff --git a/tests/integration/targets/keycloak_clientsecret_regenerate/tasks/main.yml b/tests/integration/targets/keycloak_clientsecret_regenerate/tasks/main.yml new file mode 100644 index 0000000000..9bd52698a2 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_regenerate/tasks/main.yml @@ -0,0 +1,49 @@ +--- +# 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 + +- name: Create realm + community.general.keycloak_realm: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + id: "{{ realm }}" + realm: "{{ realm }}" + state: present + +- name: Keycloak Client + community.general.keycloak_client: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + realm: "{{ realm }}" + client_id: "{{ client_id }}" + state: present + register: client + +- name: Keycloak Client regenerate clientsecret by client_id + community.general.keycloak_clientsecret_regenerate: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + realm: "{{ realm }}" + client_id: "{{ client_id }}" + register: regenerate_by_client_id + +- name: Assert that the client secret was retrieved + assert: + that: + - regenerate_by_client_id.end_state.type == "secret" + - "{{ regenerate_by_client_id.end_state.value | length }} >= 32" + +- name: Keycloak Client regenerate clientsecret by id + community.general.keycloak_clientsecret_regenerate: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + realm: "{{ realm }}" + id: "{{ client.end_state.id }}" + register: regenerate_by_id + +- name: Assert that client secret was regenerated + assert: + that: + - "{{ regenerate_by_id.end_state.value | length }} >= 32" + - regenerate_by_id.end_state.value != regenerate_by_client_id.end_state.value diff --git a/tests/integration/targets/keycloak_clientsecret_regenerate/vars/main.yml b/tests/integration/targets/keycloak_clientsecret_regenerate/vars/main.yml new file mode 100644 index 0000000000..8c913705f7 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_regenerate/vars/main.yml @@ -0,0 +1,20 @@ +--- +# 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 + +url: http://localhost:8080/auth +admin_realm: master +admin_user: admin +admin_password: password +realm: myrealm +client_id: myclient +role: myrole +description_1: desc 1 +description_2: desc 2 + +auth_args: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}"