From 6334daf244c4ff610ac860a856e1bea6b6bce845 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 12 Apr 2023 10:59:08 +0200 Subject: [PATCH 001/376] ci: fix typo and indent for TCPPING discovery --- roles/keycloak/tasks/install.yml | 4 ++-- roles/keycloak/tasks/prereqs.yml | 8 -------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index ee8a46c..864c52a 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -232,11 +232,11 @@ { "name": item, "address": 'jgroups-' + item, - "inventory_host": hostvars[item].ansible_default_ipv4.address | default(item) + '[' + keycloak_jgroups_port + ']', + "inventory_host": hostvars[item].ansible_default_ipv4.address | default(item) + '[' + (keycloak_jgroups_port | string) + ']', "value": hostvars[item].ansible_default_ipv4.address | default(item) } ] }} - loop: "{{ ansible_play_batch }}" + loop: "{{ ansible_play_batch }}" when: keycloak_ha_enabled and keycloak_ha_discovery == 'TCPPING' - name: "Deploy HA {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak.config_template_source }}" diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index 3f18964..c774c65 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -15,14 +15,6 @@ fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_ha_enabled and keycloak_db_enabled" success_msg: "{{ 'Configuring HA' if keycloak_ha_enabled else 'Configuring standalone' }}" -- name: Validate remote cache store configuration - ansible.builtin.assert: - that: - - (keycloak_remote_cache_enabled and keycloak_ha_enabled) or (not keycloak_ha_enabled) - quiet: True - fail_msg: "Cannot deploy with remote cache storage on infinispan when keycloak_ha_enabled is false" - success_msg: "{{ 'Configuring HA with infinispan remote cache storage' if keycloak_ha_enabled else 'Configuring standalone' }}" - - name: Validate credentials ansible.builtin.assert: that: From 6ac0c18842270665fc9dd53221af6b1183c08ca9 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 12 Apr 2023 11:12:32 +0200 Subject: [PATCH 002/376] fix: drop xml element not available in 7.6 --- roles/keycloak/templates/standalone-ha.xml.j2 | 1 - 1 file changed, 1 deletion(-) diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index d35a9e0..026e85c 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -376,7 +376,6 @@ - From 8d16e241c1b0da33f65c2b1c1e560e1bacdd6f8b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 14 Apr 2023 14:58:40 +0200 Subject: [PATCH 003/376] fix undefined facts when offline patching sso --- roles/keycloak/tasks/rhsso_patch.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index 0cbf002..1b1e9a6 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -3,6 +3,8 @@ - name: Set download patch archive path ansible.builtin.set_fact: patch_archive: "{{ keycloak_dest }}/{{ sso_patch_bundle }}" + patch_bundle: "{{ sso_patch_bundle }}" + patch_version: "{{ sso_patch_version }}" when: sso_patch_version is defined - name: Check download patch archive path @@ -10,6 +12,7 @@ path: "{{ patch_archive }}" register: patch_archive_path when: sso_patch_version is defined + become: yes - name: Perform patch download from RHN via JBossNetwork API delegate_to: localhost From 43d978370d5b585801b4311d84eb623c60db882e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 14 Apr 2023 15:50:48 +0200 Subject: [PATCH 004/376] bump to 1.2.2 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 71e45e6..318efcb 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.1" +version: "1.2.2" readme: README.md authors: - Romain Pelisse From c7d2bdcee35ba2437afde066a23ed416354dd339 Mon Sep 17 00:00:00 2001 From: Jonathan Wright Date: Fri, 21 Apr 2023 15:12:59 -0500 Subject: [PATCH 005/376] add configurability for XA transactions --- roles/keycloak_quarkus/defaults/main.yml | 3 +++ roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/templates/keycloak.conf.j2 | 3 +++ 3 files changed, 10 insertions(+) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index f51ce59..371180e 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -52,6 +52,9 @@ keycloak_quarkus_frontend_url: http://localhost:8080/auth # proxy address forwarding mode if the server is behind a reverse proxy. [edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge +# disable xa transactions +keycloak_quarkus_transaction_xa_enabled: True + keycloak_quarkus_metrics_enabled: False keycloak_quarkus_health_enabled: True diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 9205cef..8c27fb2 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -248,3 +248,7 @@ argument_specs: default: False type: "bool" description: "Whether to start the service in development mode (start-dev)" + keycloak_quarkus_transaction_xa_enabled: + default: True + type: bool" + description: "Enable or disable XA transactions which may not be supported by some DBMS" diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index bd9f5bf..600e9d1 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -39,6 +39,9 @@ proxy={{ keycloak_quarkus_proxy_mode }} # Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy #spi-sticky-session-encoder-infinispan-should-attach-route=false +# Transaction +transaction-xa-enabled={{ keycloak_quarkus_transaction_xa_enabled }} + # Logging #log-format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n log={{ keycloak_quarkus_log }} From d72d46c9459d3747a4db8d0b686ceaaef37babdf Mon Sep 17 00:00:00 2001 From: Jonathan Wright <8390543+jonathanspw@users.noreply.github.com> Date: Mon, 24 Apr 2023 08:50:16 -0500 Subject: [PATCH 006/376] fix typo --- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 8c27fb2..66e8adf 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -250,5 +250,5 @@ argument_specs: description: "Whether to start the service in development mode (start-dev)" keycloak_quarkus_transaction_xa_enabled: default: True - type: bool" + type: "bool" description: "Enable or disable XA transactions which may not be supported by some DBMS" From 020bc86955f45d9d9e31e49dd5c4e5a2f668b07f Mon Sep 17 00:00:00 2001 From: Jonathan Wright <8390543+jonathanspw@users.noreply.github.com> Date: Mon, 24 Apr 2023 08:52:36 -0500 Subject: [PATCH 007/376] document keycloak_quarkus_transaction_xa_enabled --- roles/keycloak_quarkus/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index de330dc..ab98d4a 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -98,6 +98,7 @@ Role Defaults |`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | +|`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | Role Variables From 1a450ea1d72b7ccfbbea2f8d9de31d6211e3b989 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 2 May 2023 17:00:17 +0200 Subject: [PATCH 008/376] ci: add galaxy tags --- galaxy.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/galaxy.yml b/galaxy.yml index 318efcb..4590f76 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -21,6 +21,8 @@ tags: - infrastructure - authentication - java + - runtimes + - middleware dependencies: "middleware_automation.common": ">=1.0.0" "ansible.posix": ">=1.4.0" From 44ad3b8e6de51dce459a1850da2cceee71ccfb28 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 2 May 2023 18:05:12 +0200 Subject: [PATCH 009/376] add galaxy tag --- galaxy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/galaxy.yml b/galaxy.yml index 4590f76..26f69f6 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -23,6 +23,7 @@ tags: - java - runtimes - middleware + - A4MW dependencies: "middleware_automation.common": ">=1.0.0" "ansible.posix": ">=1.4.0" From f566917bc2c5edfed014f130b7a509371a2f31dc Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 3 May 2023 08:54:20 +0200 Subject: [PATCH 010/376] ci: rename galaxy tag --- .github/workflows/ci.yml | 5 +++-- .github/workflows/docs.yml | 3 ++- .github/workflows/release.yml | 3 ++- galaxy.yml | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 54e3e9e..3764e8f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python_version: ["3.9"] + python_version: ["3.10"] steps: - name: Check out code uses: actions/checkout@v2 @@ -24,9 +24,10 @@ jobs: path: ansible_collections/middleware_automation/keycloak - name: Set up Python ${{ matrix.python_version }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python_version }} + cache: 'pip' - name: Install yamllint, ansible and molecule run: | diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 7163a00..e46b1e8 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -32,9 +32,10 @@ jobs: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.9 + cache: 'pip' - name: Install doc dependencies run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f8cdffe..3f47356 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,9 +24,10 @@ jobs: token: ${{ secrets.TRIGGERING_PAT }} - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: python-version: "3.x" + cache: 'pip' - name: Get current version id: get_version diff --git a/galaxy.yml b/galaxy.yml index 26f69f6..d4232dc 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -23,7 +23,7 @@ tags: - java - runtimes - middleware - - A4MW + - a4mw dependencies: "middleware_automation.common": ">=1.0.0" "ansible.posix": ">=1.4.0" From a3bffe94014af171132463a490cfc2392206e303 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 3 May 2023 15:23:46 +0200 Subject: [PATCH 011/376] Bump to 1.2.3 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index d4232dc..5b34de2 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.2" +version: "1.2.3" readme: README.md authors: - Romain Pelisse From 706677910b8b0d133f1329fca92db36e47d1d664 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 5 May 2023 11:07:42 +0200 Subject: [PATCH 012/376] ci: update apt before installing hub --- .github/workflows/docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index e46b1e8..071821d 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -42,6 +42,7 @@ jobs: python -m pip install --upgrade pip pip install -r ansible_collections/middleware_automation/keycloak/docs/requirements.txt pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt + sudo apt --fix-missing update sudo apt install -y sed hub - name: Create default collection path From fd0a4e44928097a88893e0640c8adf87befd274e Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 9 May 2023 11:45:25 +0200 Subject: [PATCH 013/376] Close #76 - Keycloak role: fix deprecation warning for `ipaddr` --- .../templates/15.0.8/standalone-infinispan.xml.j2 | 6 +++--- .../keycloak/templates/9.0.2/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/standalone-ha.xml.j2 | 8 ++++---- roles/keycloak/templates/standalone-infinispan.xml.j2 | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 index 4198b83..be61837 100644 --- a/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 @@ -631,7 +631,7 @@ -{% if keycloak_modcluster.enabled %} +{% if keycloak_modcluster.enabled %} @@ -639,7 +639,7 @@ -{% endif %} +{% endif %} @@ -728,7 +728,7 @@ {% if ansible_default_ipv4 is defined %} - + {% else %} {% endif %} diff --git a/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 b/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 index 2b2842b..9e0ae66 100644 --- a/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 @@ -725,7 +725,7 @@ {% if ansible_default_ipv4 is defined %} - + {% else %} {% endif %} diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 026e85c..75df7ab 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -584,7 +584,7 @@ -{% if keycloak_modcluster.enabled %} +{% if keycloak_modcluster.enabled %} @@ -592,7 +592,7 @@ -{% endif %} +{% endif %} @@ -638,7 +638,7 @@ - + @@ -652,7 +652,7 @@ {% if ansible_default_ipv4 is defined %} - + {% else %} {% endif %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index e326924..30a6e20 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -622,7 +622,7 @@ -{% if keycloak_modcluster.enabled %} +{% if keycloak_modcluster.enabled %} @@ -630,7 +630,7 @@ -{% endif %} +{% endif %} @@ -676,7 +676,7 @@ - + @@ -690,7 +690,7 @@ {% if ansible_default_ipv4 is defined %} - + {% else %} {% endif %} From aad373a8e9ab39125059a727ea63b86f8196e1af Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 9 May 2023 11:03:55 +0200 Subject: [PATCH 014/376] Close #74 - add `sqlserver` support to keycloak role --- roles/keycloak/README.md | 4 ++-- roles/keycloak/defaults/main.yml | 5 ++++- roles/keycloak/meta/argument_specs.yml | 2 +- roles/keycloak/tasks/prereqs.yml | 2 +- roles/keycloak/vars/main.yml | 22 ++++++++++++++++++++++ 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index aff6a1e..f252be9 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -83,7 +83,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| |`keycloak_offline_install` | perform an offline install | `False`| -|`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| +|`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| |`keycloak_version`| keycloak.org package version | `18.0.2` | |`keycloak_dest`| Installation root path | `/opt/keycloak` | |`keycloak_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}` | @@ -127,7 +127,7 @@ The following variables are _required_ only when `keycloak_ha_enabled` is True: |`keycloak_modcluster_url` | _deprecated_ Host for the modcluster reverse proxy | `localhost` | |`keycloak_modcluster_port` | _deprecated_ Port for the modcluster reverse proxy | `6666` | |`keycloak_modcluster_urls` | List of {host,port} dicts for the modcluster reverse proxies | `[ { localhost:6666 } ]` | -|`keycloak_jdbc_engine` | backend database engine when db is enabled: [ postgres, mariadb ] | `postgres` | +|`keycloak_jdbc_engine` | backend database engine when db is enabled: [ postgres, mariadb, sqlserver ] | `postgres` | |`keycloak_infinispan_url` | URL for the infinispan remote-cache server | `localhost:11122` | |`keycloak_infinispan_user` | username for connecting to infinispan | `supervisor` | |`keycloak_infinispan_pass` | password for connecting to infinispan | `supervisor` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 795768f..da84f13 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -79,7 +79,7 @@ keycloak_infinispan_use_ssl: False keycloak_infinispan_trust_store_path: /etc/pki/java/cacerts keycloak_infinispan_trust_store_password: changeit -### database backend engine: values [ 'postgres', 'mariadb' ] +### database backend engine: values [ 'postgres', 'mariadb', 'sqlserver' ] keycloak_jdbc_engine: postgres ### database backend credentials keycloak_db_user: keycloak-user @@ -94,5 +94,8 @@ keycloak_default_jdbc: mariadb: url: 'jdbc:mariadb://localhost:3306/keycloak' version: 2.7.4 + sqlserver: + url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;' + version: 12.2.0 # role specific vars keycloak_no_log: True diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 2fe1e05..9f72b2e 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -237,7 +237,7 @@ argument_specs: keycloak_jdbc_engine: # line 72 of keycloak/defaults/main.yml default: "postgres" - description: "Backend database flavour when db is enabled: [ postgres, mariadb ]" + description: "Backend database flavour when db is enabled: [ postgres, mariadb, sqlserver ]" type: "str" keycloak_db_user: # line 74 of keycloak/defaults/main.yml diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index c774c65..418a574 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -27,7 +27,7 @@ - name: Validate persistence configuration ansible.builtin.assert: that: - - keycloak_jdbc_engine is defined and keycloak_jdbc_engine in [ 'postgres', 'mariadb' ] + - keycloak_jdbc_engine is defined and keycloak_jdbc_engine in [ 'postgres', 'mariadb', 'sqlserver' ] - keycloak_jdbc_url | length > 0 - keycloak_db_user | length > 0 - keycloak_db_pass | length > 0 diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index f14e4b7..d44ee5a 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -56,6 +56,28 @@ keycloak_jdbc: ping_data varbinary(5000) DEFAULT NULL, PRIMARY KEY (own_addr, cluster_name)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin + sqlserver: + enabled: "{{ (keycloak_ha_enabled or keycloak_db_enabled) and keycloak_jdbc_engine == 'sqlserver' }}" + driver_class: com.microsoft.sqlserver.jdbc.SQLServerDriver + xa_datasource_class: com.microsoft.sqlserver.jdbc.SQLServerXADataSource + driver_module_name: "com.microsoft.sqlserver" + driver_module_dir: "{{ keycloak_jboss_home }}/modules/com/microsoft/sqlserver/main" + driver_version: "{{ keycloak_jdbc_driver_version }}" + driver_jar_filename: "mssql-java-client-{{ keycloak_jdbc_driver_version }}.jar" + driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/{{ keycloak_jdbc_driver_version }}.jre11/mssql-jdbc-{{ keycloak_jdbc_driver_version }}.jre11.jar" # e.g., https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar + connection_url: "{{ keycloak_jdbc_url }}" + db_user: "{{ keycloak_db_user }}" + db_password: "{{ keycloak_db_pass }}" + initialize_db: > + IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[JGROUPSPING]') AND type in (N'U')) + BEGIN + CREATE TABLE JGROUPSPING ( + own_addr varchar(200) NOT NULL, + cluster_name varchar(200) NOT NULL, + updated DATETIME2 DEFAULT SYSUTCDATETIME(), + ping_data varbinary(5000) DEFAULT NULL, + PRIMARY KEY (own_addr, cluster_name)) + END # reverse proxy mod_cluster keycloak_modcluster: From e4811221be40e03c9cfe5e38a927b930168275b0 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 9 May 2023 15:25:41 +0200 Subject: [PATCH 015/376] ci: fix release wf, bump to 1.2.4 --- .github/workflows/release.yml | 1 + galaxy.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3f47356..ff64240 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,6 +48,7 @@ jobs: run: | python -m pip install --upgrade pip pip install ansible-core antsibull + sudo apt --fix-missing update sudo apt install -y sed hub - name: Build collection diff --git a/galaxy.yml b/galaxy.yml index 5b34de2..a19e284 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.3" +version: "1.2.4" readme: README.md authors: - Romain Pelisse From 7471e07921449ebb5ae4d7a0492347ba0bd810bc Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 9 May 2023 13:49:15 +0000 Subject: [PATCH 016/376] Update changelog for release 1.2.4 --- CHANGELOG.rst | 15 +++++++++++++++ changelogs/changelog.yaml | 22 ++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index acf89df..145ab2e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,21 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.2.4 +====== + +Minor Changes +------------- + +- Add ``sqlserver`` to keycloak role jdbc configurations `#78 `_ +- Add configurability for XA transactions `#73 `_ + +Bugfixes +-------- + +- Fix deprecation warning for ``ipaddr`` `#77 `_ +- Fix undefined facts when offline patching sso `#71 `_ + v1.2.1 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 549540c..330081c 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -181,3 +181,25 @@ releases: - 68.yaml - 69.yaml release_date: '2023-04-11' + 1.2.4: + changes: + bugfixes: + - 'Fix deprecation warning for ``ipaddr`` `#77 `_ + + ' + - 'Fix undefined facts when offline patching sso `#71 `_ + + ' + minor_changes: + - 'Add ``sqlserver`` to keycloak role jdbc configurations `#78 `_ + + ' + - 'Add configurability for XA transactions `#73 `_ + + ' + fragments: + - 71.yaml + - 73.yaml + - 77.yaml + - 78.yaml + release_date: '2023-05-09' From 01fd2cc4fdb1037577b9a6e48b3120fbc9c542d7 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 9 May 2023 16:44:16 +0200 Subject: [PATCH 017/376] Bump to 1.2.5 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index a19e284..27c0e21 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.4" +version: "1.2.5" readme: README.md authors: - Romain Pelisse From 370d424b24fcc6d217f6fb2c468aeb689e7e44a2 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Fri, 12 May 2023 08:57:36 +0200 Subject: [PATCH 018/376] Close #80 - introduce systemd restart behavior --- roles/keycloak/README.md | 6 +++++- roles/keycloak/defaults/main.yml | 6 +++++- roles/keycloak/meta/argument_specs.yml | 16 ++++++++++++++++ roles/keycloak/tasks/install.yml | 2 +- roles/keycloak/templates/keycloak.service.j2 | 9 +++++++++ 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index f252be9..3508a71 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -72,6 +72,10 @@ Role Defaults |`keycloak_config_standalone_xml`| filename for configuration | `keycloak.xml` | |`keycloak_service_user`| posix account username | `keycloak` | |`keycloak_service_group`| posix account group | `keycloak` | +|`keycloak_service_restart_on_failure`| systemd restart-on-failure behavior activation |True +|`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` if `keycloak_service_restart_on_failure` else `` +|`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` if `keycloak_service_restart_on_failure` else `` +|`keycloak_service_restartsec`| systemd RestartSec | `10s` if `keycloak_service_restart_on_failure` else `` |`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` | |`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` | |`keycloak_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path | `None` | @@ -116,7 +120,7 @@ The following are a set of _required_ variables for the role: | Variable | Description | |:---------|:------------| |`keycloak_admin_password`| Password for the administration console user account (minimum 12 characters) | -|`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth` | +|`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | The following variables are _required_ only when `keycloak_ha_enabled` is True: diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index da84f13..5a54ce3 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -23,6 +23,10 @@ keycloak_service_name: keycloak keycloak_service_desc: Keycloak keycloak_service_start_delay: 10 keycloak_service_start_retries: 25 +keycloak_service_restart_on_failure: True +keycloak_service_startlimitintervalsec: "{{ 300 if keycloak_service_restart_on_failure else '' }}" +keycloak_service_startlimitburst: "{{ 5 if keycloak_service_restart_on_failure else '' }}" +keycloak_service_restartsec: "{{ '10s' if keycloak_service_restart_on_failure else '' }}" keycloak_configure_firewalld: False @@ -67,7 +71,7 @@ keycloak_modcluster_urls: port: "{{ keycloak_modcluster_port }}" ### keycloak frontend url -keycloak_frontend_url: http://localhost:8080/auth +keycloak_frontend_url: http://localhost:8080/auth/ ### infinispan remote caches access (hotrod) keycloak_infinispan_user: supervisor diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 9f72b2e..e348973 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -290,6 +290,22 @@ argument_specs: default: "25" description: "How many time should Ansible retry to connect to the service after it was started, before failing." type: "int" + keycloak_service_restart_on_failure: + default: true + description: "systemd restart-on-failure behavior activation for keycloak" + type: "bool" + keycloak_service_startlimitintervalsec: + default: 300 + description: "systemd StartLimitIntervalSec for keycloak" + type: "int" + keycloak_service_startlimitburst: + default: 5 + description: "systemd StartLimitBurst for keycloak" + type: "int" + keycloak_service_restartsec: + default: "5s" + description: "systemd RestartSec for keycloak" + type: "str" keycloak_no_log: default: true type: "bool" diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 864c52a..f9c9028 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -266,5 +266,5 @@ - restart keycloak when: - keycloak_ha_enabled - - keycloak_remote_cache_enabled + - keycloak_remote_cache_enabled - keycloak_config_override_template | length == 0 diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index 0fcecbf..0dec52a 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -2,6 +2,11 @@ [Unit] Description={{ keycloak.service_name }} Server After=network.target +{% if keycloak_service_restart_on_failure %} +StartLimitIntervalSec={{ keycloak_service_startlimitintervalsec }} +StartLimitBurst={{ keycloak_service_startlimitburst }} +{% endif %} + [Service] Type=forking @@ -12,6 +17,10 @@ ExecStop={{ keycloak_dest }}/keycloak-service.sh stop TimeoutStartSec=30 TimeoutStopSec=30 LimitNOFILE=102642 +{% if keycloak_service_restart_on_failure %} +Restart=on-failure +RestartSec={{ keycloak_service_restartsec }} +{% endif %} [Install] WantedBy=multi-user.target From fd375a141d0866c75180ccef7062784b6e0580da Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 22 May 2023 16:12:25 +0200 Subject: [PATCH 019/376] ci: update linter settings, fix new linter issues --- .ansible-lint | 5 +++-- molecule/default/verify.yml | 7 ++++--- molecule/quarkus/prepare.yml | 25 +++++++++++++++---------- molecule/quarkus/verify.yml | 20 ++++++++++++-------- roles/keycloak/tasks/rhsso_patch.yml | 6 +++--- 5 files changed, 37 insertions(+), 26 deletions(-) diff --git a/.ansible-lint b/.ansible-lint index eaa75d0..ccabc00 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -21,19 +21,20 @@ warn_list: - experimental - ignore-errors - no-handler - - fqcn-builtins - no-log-password - jinja[spacing] - jinja[invalid] - meta-no-tags - - name[template] - name[casing] - fqcn[action] - schema[meta] + - var-naming[no-role-prefix] + - key-order[task] skip_list: - vars_should_not_be_used - file_is_small_enough + - name[template] use_default_rules: true parseable: true diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 061279d..86047a4 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -15,8 +15,11 @@ - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" - name: Verify we are running on requested jvm - shell: | + ansible.builtin.shell: | + set -o pipefail ps -ef | grep /usr/lib/jvm/java-11 | grep -v grep + args: + executable: /bin/bash changed_when: no - name: Verify token api call ansible.builtin.uri: @@ -48,8 +51,6 @@ headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" register: keycloak_query_clients - - debug: - msg: "{{ keycloak_query_clients.json | selectattr('clientId','equalto','TestClient') }}" - name: Verify expected config ansible.builtin.assert: that: diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index f54dbb8..4b85c14 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -11,25 +11,30 @@ ansible.builtin.set_fact: hera_home: "{{ lookup('env', 'HERA_HOME') }}" - - ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' + - name: Create certificate request + ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' delegate_to: localhost + changed_when: False - - block: - - ansible.builtin.lineinfile: - dest: /etc/hosts - line: "127.0.0.1 instance" - state: present - delegate_to: localhost - become: yes + - name: Set /etc/hosts + ansible.builtin.lineinfile: + dest: /etc/hosts + line: "127.0.0.1 instance" + state: present + delegate_to: localhost + become: yes when: - hera_home is defined - hera_home | length == 0 - - ansible.builtin.file: + - name: Create conf directory # risky-file-permissions in test user account does not exist yet + ansible.builtin.file: state: directory path: /opt/keycloak/keycloak-18.0.0/conf/ + mode: 0755 - - ansible.builtin.copy: + - name: Copy certificates + ansible.builtin.copy: src: "{{ item }}" dest: "/opt/keycloak/keycloak-18.0.0/conf/{{ item }}" mode: 0444 diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 1d4e5ae..6a3d547 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -4,26 +4,30 @@ tasks: - name: Populate service facts ansible.builtin.service_facts: + - name: Check if keycloak service started ansible.builtin.assert: that: - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" - - set_fact: + - name: Set internal envvar + ansible.builtin.set_fact: hera_home: "{{ lookup('env', 'HERA_HOME') }}" - - block: - - name: Fetch openID config - shell: | + - name: Verify openid config + block: + - name: Fetch openID config # noqa command-instead-of-module + ansible.builtin.shell: | + set -o pipefail curl https://instance:8443/realms/master/.well-known/openid-configuration -k | jq . + args: + executable: /bin/bash delegate_to: localhost register: openid_config - - debug: - msg: " {{ openid_config.stdout | from_json }}" - delegate_to: localhost + changed_when: False - name: Verify endpoint URLs - assert: + ansible.builtin.assert: that: - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://instance/realms/master/protocol/openid-connect/ext/ciba/auth' - (openid_config.stdout | from_json)['issuer'] == 'https://instance/realms/master' diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index 1b1e9a6..7f00a50 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -35,14 +35,14 @@ run_once: yes - name: Determine patch versions list - set_fact: + ansible.builtin.set_fact: filtered_versions: "{{ rhn_products.results | map(attribute='file_path') | select('match', '^[^/]*/rh-sso-.*[0-9]*[.][0-9]*[.][0-9]*.*$') | map('regex_replace','[^/]*/rh-sso-([0-9]*[.][0-9]*[.][0-9]*)-.*','\\1' ) | list | unique }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 delegate_to: localhost run_once: yes - name: Determine latest version - set_fact: + ansible.builtin.set_fact: sso_latest_version: "{{ filtered_versions | middleware_automation.keycloak.version_sort | last }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 delegate_to: localhost @@ -58,7 +58,7 @@ run_once: yes - name: "Determine selected patch from supplied version: {{ sso_patch_version }}" - set_fact: + ansible.builtin.set_fact: rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/' + sso_patch_bundle + '$') }}" patch_bundle: "{{ sso_patch_bundle }}" patch_version: "{{ sso_patch_version }}" From 98e1633c4352f1bdbbe9c961cb9a98b7b5a1b5bb Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 22 May 2023 16:24:28 +0200 Subject: [PATCH 020/376] ci: new linter rules take 2 --- .ansible-lint | 1 + molecule/default/verify.yml | 2 +- molecule/quarkus/verify.yml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.ansible-lint b/.ansible-lint index ccabc00..92e5eaf 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -30,6 +30,7 @@ warn_list: - schema[meta] - var-naming[no-role-prefix] - key-order[task] + - blocked_modules skip_list: - vars_should_not_be_used diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 86047a4..490b38c 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -14,7 +14,7 @@ that: - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" - - name: Verify we are running on requested jvm + - name: Verify we are running on requested jvm # noqa blocked_modules command-instead-of-module ansible.builtin.shell: | set -o pipefail ps -ef | grep /usr/lib/jvm/java-11 | grep -v grep diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 6a3d547..553c4d6 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -17,7 +17,7 @@ - name: Verify openid config block: - - name: Fetch openID config # noqa command-instead-of-module + - name: Fetch openID config # noqa blocked_modules command-instead-of-module ansible.builtin.shell: | set -o pipefail curl https://instance:8443/realms/master/.well-known/openid-configuration -k | jq . From c4b4be3c3b9a55936415f3caa54eae9c69d80ddd Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 25 May 2023 11:10:18 +0200 Subject: [PATCH 021/376] add variable for force_frontend_url --- .gitignore | 2 + galaxy.yml | 2 +- plugins/filter/version_sort.py | 52 ------------------- plugins/module_utils/version.py | 22 -------- roles/keycloak/README.md | 8 +-- roles/keycloak/defaults/main.yml | 1 + roles/keycloak/meta/argument_specs.yml | 4 ++ roles/keycloak/tasks/rhsso_patch.yml | 2 +- roles/keycloak/templates/standalone-ha.xml.j2 | 2 +- .../templates/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/standalone.xml.j2 | 2 +- roles/keycloak/vars/main.yml | 1 + 12 files changed, 17 insertions(+), 83 deletions(-) delete mode 100644 plugins/filter/version_sort.py delete mode 100644 plugins/module_utils/version.py diff --git a/.gitignore b/.gitignore index 9cc2eb2..e1daa92 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ *.zip .tmp .cache +.vscode/ +__pycache__/ docs/plugins/ docs/roles/ docs/_build/ diff --git a/galaxy.yml b/galaxy.yml index 27c0e21..76205f1 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -25,7 +25,7 @@ tags: - middleware - a4mw dependencies: - "middleware_automation.common": ">=1.0.0" + "middleware_automation.common": ">=1.1.0" "ansible.posix": ">=1.4.0" repository: https://github.com/ansible-middleware/keycloak documentation: https://ansible-middleware.github.io/keycloak diff --git a/plugins/filter/version_sort.py b/plugins/filter/version_sort.py deleted file mode 100644 index beb44cb..0000000 --- a/plugins/filter/version_sort.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (C) 2021 Eric Lavarde -# 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 - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -DOCUMENTATION = ''' - name: version_sort - short_description: Sort a list according to version order instead of pure alphabetical one - version_added: 2.2.0 - author: Eric L. (@ericzolf) - description: - - Sort a list according to version order instead of pure alphabetical one. - options: - _input: - description: A list of strings to sort. - type: list - elements: string - required: true -''' - -EXAMPLES = ''' -- name: Convert list of tuples into dictionary - ansible.builtin.set_fact: - dictionary: "{{ ['2.1', '2.10', '2.9'] | middleware_automation.keycloak.version_sort }}" - # Result is ['2.1', '2.9', '2.10'] -''' - -RETURN = ''' - _value: - description: The list of strings sorted by version. - type: list - elements: string -''' - -from ansible_collections.middleware_automation.keycloak.plugins.module_utils.version import LooseVersion - - -def version_sort(value, reverse=False): - '''Sort a list according to loose versions so that e.g. 2.9 is smaller than 2.10''' - return sorted(value, key=LooseVersion, reverse=reverse) - - -class FilterModule(object): - ''' Version sort filter ''' - - def filters(self): - return { - 'version_sort': version_sort - } diff --git a/plugins/module_utils/version.py b/plugins/module_utils/version.py deleted file mode 100644 index 3699881..0000000 --- a/plugins/module_utils/version.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2021, Felix Fontein -# 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 - -"""Provide version object to compare version numbers.""" - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -from ansible.module_utils.six import raise_from - -try: - from ansible.module_utils.compat.version import LooseVersion # noqa: F401, pylint: disable=unused-import -except ImportError: - try: - from distutils.version import LooseVersion # noqa: F401, pylint: disable=unused-import - except ImportError as exc: - msg = 'To use this plugin or module with ansible-core 2.11, you need to use Python < 3.12 with distutils.version present' - raise_from(ImportError(msg), exc) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 3508a71..5c882cc 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -73,9 +73,9 @@ Role Defaults |`keycloak_service_user`| posix account username | `keycloak` | |`keycloak_service_group`| posix account group | `keycloak` | |`keycloak_service_restart_on_failure`| systemd restart-on-failure behavior activation |True -|`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` if `keycloak_service_restart_on_failure` else `` -|`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` if `keycloak_service_restart_on_failure` else `` -|`keycloak_service_restartsec`| systemd RestartSec | `10s` if `keycloak_service_restart_on_failure` else `` +|`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` if `keycloak_service_restart_on_failure` else `` | +|`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` if `keycloak_service_restart_on_failure` else `` | +|`keycloak_service_restartsec`| systemd RestartSec | `10s` if `keycloak_service_restart_on_failure` else `` | |`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` | |`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` | |`keycloak_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path | `None` | @@ -110,7 +110,7 @@ Role Defaults |`keycloak_force_install` | Remove pre-existing versions of service | `False` | |`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port }}` | |`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port }}` | - +|`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `False` | Role Variables -------------- diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 5a54ce3..025a815 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -72,6 +72,7 @@ keycloak_modcluster_urls: ### keycloak frontend url keycloak_frontend_url: http://localhost:8080/auth/ +keycloak_frontend_url_force: False ### infinispan remote caches access (hotrod) keycloak_infinispan_user: supervisor diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index e348973..3a7572a 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -199,6 +199,10 @@ argument_specs: default: "http://localhost" description: "Frontend URL for keycloak endpoints when a reverse proxy is used" type: "str" + keycloak_frontend_url_force: + default: False + description: "Force backend requests to use the frontend URL" + type: "bool" keycloak_infinispan_user: # line 62 of keycloak/defaults/main.yml default: "supervisor" diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index 7f00a50..b03b55c 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -43,7 +43,7 @@ - name: Determine latest version ansible.builtin.set_fact: - sso_latest_version: "{{ filtered_versions | middleware_automation.keycloak.version_sort | last }}" + sso_latest_version: "{{ filtered_versions | middleware_automation.common.version_sort | last }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 delegate_to: localhost run_once: yes diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 75df7ab..14a6e3a 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -573,7 +573,7 @@ - + diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 30a6e20..5f0ea5b 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -611,7 +611,7 @@ - + diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 438a0da..6ba9efd 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -517,7 +517,7 @@ - + diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index d44ee5a..cffbac3 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -84,6 +84,7 @@ keycloak_modcluster: enabled: "{{ keycloak_ha_enabled or keycloak_modcluster_enabled }}" reverse_proxy_urls: "{{ keycloak_modcluster_urls }}" frontend_url: "{{ keycloak_frontend_url }}" + force_frontend_url: "{{ keycloak_frontend_url_force }}" # infinispan keycloak_remotecache: From 19f1750a33c5460d06ad2ace0a5f415113a11e1f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 25 May 2023 11:47:19 +0200 Subject: [PATCH 022/376] Add db pool validation configuration --- roles/keycloak/README.md | 18 ++++++++++++++---- roles/keycloak/defaults/main.yml | 6 ++++++ roles/keycloak/meta/argument_specs.yml | 16 ++++++++++++++++ roles/keycloak/templates/standalone-ha.xml.j2 | 6 ++++++ .../templates/standalone-infinispan.xml.j2 | 6 ++++++ roles/keycloak/templates/standalone.xml.j2 | 6 ++++++ roles/keycloak/vars/main.yml | 3 +++ 7 files changed, 57 insertions(+), 4 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 5c882cc..19f0ed9 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -111,6 +111,11 @@ Role Defaults |`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port }}` | |`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port }}` | |`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `False` | +|`keycloak_db_background_validation` | Enable background validation of database connection | `False` | +|`keycloak_db_background_validation_millis`| How frequenly the connection pool is validated in the background | `10000` if background validation enabled | +|`keycloak_db_background_validate_on_match` Enable validate on match for database connections | `False` | +|`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | + Role Variables -------------- @@ -123,7 +128,7 @@ The following are a set of _required_ variables for the role: |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | -The following variables are _required_ only when `keycloak_ha_enabled` is True: +The following parameters are _required_ only when `keycloak_ha_enabled` is True: | Variable | Description | Default | |:---------|:------------|:--------| @@ -141,7 +146,7 @@ The following variables are _required_ only when `keycloak_ha_enabled` is True: |`keycloak_infinispan_trust_store_password`| Password for opening truststore | `changeit` | -The following variables are _required_ only when `keycloak_db_enabled` is True: +The following parameters are _required_ only when `keycloak_db_enabled` is True: | Variable | Description | Default | |:---------|:------------|:---------| @@ -151,6 +156,13 @@ The following variables are _required_ only when `keycloak_db_enabled` is True: |`keycloak_db_pass` | password for connecting to postgres | `keycloak-pass` | +The following variables are _optional_: + +| Variable | Description | +|:---------|:------------| +|`keycloak_db_valid_conn_sql` | Override the default database connection validation query sql | + + Example Playbook ----------------- @@ -161,8 +173,6 @@ Example Playbook - hosts: ... vars: keycloak_admin_password: "remembertochangeme" - collections: - - middleware_automation.keycloak roles: - middleware_automation.keycloak.keycloak ``` diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 025a815..68e473b 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -89,6 +89,12 @@ keycloak_jdbc_engine: postgres ### database backend credentials keycloak_db_user: keycloak-user keycloak_db_pass: keycloak-pass +## connection validation +keycloak_db_background_validation: False +keycloak_db_background_validation_millis: "{{ 10000 if keycloak_db_background_validation else 0 }}" +keycloak_db_background_validate_on_match: False +# variable to override database connection validation query +keycloak_db_valid_conn_sql: keycloak_jdbc_url: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].url }}" keycloak_jdbc_driver_version: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].version }}" # override the variables above, following defaults show minimum supported versions diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 3a7572a..9441fff 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -318,6 +318,22 @@ argument_specs: default: "{{ True if keycloak_ha_enabled else False }}" description: "Enable remote cache store when in clustered ha configurations" type: "bool" + keycloak_db_background_validation: + default: False + description: "Enable background validation of database connection" + type: "bool" + keycloak_db_background_validation_millis: + default: "{{ 10000 if keycloak_db_background_validation else 0 }}" + description: "How frequenly the connection pool is validated in the background" + type: 'int' + keycloak_db_background_validate_on_match: + default: False + description: "Enable validate on match for database connections" + type: "bool" + keycloak_db_valid_conn_sql: + required: False + description: "Override the default database connection validation query sql" + type: "str" downstream: options: sso_version: diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 14a6e3a..ca9f4f9 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -136,6 +136,12 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].db_user }} {{ keycloak_jdbc[keycloak_jdbc_engine].db_password }} + + {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} + {{ keycloak_db_background_validate_on_match }} + {{ keycloak_db_background_validation }} + {{ keycloak_db_background_validation_millis }} + {% else %} jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE h2 diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 5f0ea5b..ba75cd2 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -136,6 +136,12 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].db_user }} {{ keycloak_jdbc[keycloak_jdbc_engine].db_password }} + + {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} + {{ keycloak_db_background_validate_on_match }} + {{ keycloak_db_background_validation }} + {{ keycloak_db_background_validation_millis }} + {% else %} jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE h2 diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 6ba9efd..4f538d0 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -123,6 +123,12 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].db_user }} {{ keycloak_jdbc[keycloak_jdbc_engine].db_password }} + + {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} + {{ keycloak_db_background_validate_on_match }} + {{ keycloak_db_background_validation }} + {{ keycloak_db_background_validation_millis }} + {% else %} jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE h2 diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index cffbac3..993e841 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -29,6 +29,7 @@ keycloak_jdbc: connection_url: "{{ keycloak_jdbc_url }}" db_user: "{{ keycloak_db_user }}" db_password: "{{ keycloak_db_pass }}" + validate_query: "{{ keycloak_db_valid_conn_sql | default('select 1') }}" initialize_db: > CREATE TABLE IF NOT EXISTS JGROUPSPING ( own_addr varchar(200) NOT NULL, @@ -48,6 +49,7 @@ keycloak_jdbc: connection_url: "{{ keycloak_jdbc_url }}" db_user: "{{ keycloak_db_user }}" db_password: "{{ keycloak_db_pass }}" + validate_query: "{{ keycloak_db_valid_conn_sql | default('select 1') }}" initialize_db: > CREATE TABLE IF NOT EXISTS JGROUPSPING ( own_addr varchar(200) NOT NULL, @@ -68,6 +70,7 @@ keycloak_jdbc: connection_url: "{{ keycloak_jdbc_url }}" db_user: "{{ keycloak_db_user }}" db_password: "{{ keycloak_db_pass }}" + validate_query: "{{ keycloak_db_valid_conn_sql | default('select 1') }}" initialize_db: > IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[JGROUPSPING]') AND type in (N'U')) BEGIN From 2be35f9a674fe848d35eea0be762a6399d8e6ad8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 26 May 2023 14:28:52 +0200 Subject: [PATCH 023/376] typo in readme --- roles/keycloak/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 19f0ed9..d4cb6c9 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -113,7 +113,7 @@ Role Defaults |`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `False` | |`keycloak_db_background_validation` | Enable background validation of database connection | `False` | |`keycloak_db_background_validation_millis`| How frequenly the connection pool is validated in the background | `10000` if background validation enabled | -|`keycloak_db_background_validate_on_match` Enable validate on match for database connections | `False` | +|`keycloak_db_background_validate_on_match` | Enable validate on match for database connections | `False` | |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | From aaae1d1129801d88f80271228337808ad1a798df Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 26 May 2023 16:31:13 +0200 Subject: [PATCH 024/376] Allow to configure admin_url --- roles/keycloak/README.md | 2 ++ roles/keycloak/defaults/main.yml | 1 + roles/keycloak/meta/argument_specs.yml | 4 ++++ roles/keycloak/templates/standalone-ha.xml.j2 | 3 +++ roles/keycloak/templates/standalone-infinispan.xml.j2 | 3 +++ roles/keycloak/templates/standalone.xml.j2 | 3 +++ roles/keycloak/vars/main.yml | 1 + 7 files changed, 17 insertions(+) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index d4cb6c9..3fc8a61 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -117,6 +117,7 @@ Role Defaults |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | + Role Variables -------------- @@ -161,6 +162,7 @@ The following variables are _optional_: | Variable | Description | |:---------|:------------| |`keycloak_db_valid_conn_sql` | Override the default database connection validation query sql | +|`keycloak_admin_url` | Override the default administration endpoint URL | Example Playbook diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 68e473b..aa52d74 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -73,6 +73,7 @@ keycloak_modcluster_urls: ### keycloak frontend url keycloak_frontend_url: http://localhost:8080/auth/ keycloak_frontend_url_force: False +keycloak_admin_url: ### infinispan remote caches access (hotrod) keycloak_infinispan_user: supervisor diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 9441fff..0dc4cb3 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -334,6 +334,10 @@ argument_specs: required: False description: "Override the default database connection validation query sql" type: "str" + keycloak_admin_url: + required: False + description: "Override the default administration endpoint URL" + type: "str" downstream: options: sso_version: diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index ca9f4f9..67f5da8 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -580,6 +580,9 @@ +{% if keycloak_modcluster.admin_url | length > 0 %} + +{% endif %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index ba75cd2..cea9c87 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -618,6 +618,9 @@ +{% if keycloak_modcluster.admin_url | length > 0 %} + +{% endif %} diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 4f538d0..e38e1f0 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -524,6 +524,9 @@ +{% if keycloak_modcluster.admin_url | length > 0 %} + +{% endif %} diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 993e841..638ed3d 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -88,6 +88,7 @@ keycloak_modcluster: reverse_proxy_urls: "{{ keycloak_modcluster_urls }}" frontend_url: "{{ keycloak_frontend_url }}" force_frontend_url: "{{ keycloak_frontend_url_force }}" + admin_url: "{{ keycloak_admin_url | default('') }}" # infinispan keycloak_remotecache: From b7eef6a720aac4e779eb5b6448f28e0f0c78b263 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 26 May 2023 21:00:15 +0000 Subject: [PATCH 025/376] Update changelog for release 1.2.5 --- CHANGELOG.rst | 11 +++++++++++ changelogs/changelog.yaml | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 145ab2e..87d2470 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,17 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.2.5 +====== + +Minor Changes +------------- + +- Add configuration for database connection pool validation `#85 `_ +- Allow to configure administration endpoint URL `#86 `_ +- Allow to force backend URLs to frontend URLs `#84 `_ +- Introduce systemd unit restart behavior `#81 `_ + v1.2.4 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 330081c..779b2bd 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -203,3 +203,24 @@ releases: - 77.yaml - 78.yaml release_date: '2023-05-09' + 1.2.5: + changes: + minor_changes: + - 'Add configuration for database connection pool validation `#85 `_ + + ' + - 'Allow to configure administration endpoint URL `#86 `_ + + ' + - 'Allow to force backend URLs to frontend URLs `#84 `_ + + ' + - 'Introduce systemd unit restart behavior `#81 `_ + + ' + fragments: + - 81.yaml + - 84.yaml + - 85.yaml + - 86.yaml + release_date: '2023-05-26' From b77c166945ac5b5059309afe1a80065c68110dfb Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Wed, 31 May 2023 11:12:24 +0200 Subject: [PATCH 026/376] change xa_datasource_class for mariadb jdbc configuration --- roles/keycloak/vars/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 638ed3d..6486559 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -40,7 +40,7 @@ keycloak_jdbc: mariadb: enabled: "{{ (keycloak_ha_enabled or keycloak_db_enabled) and keycloak_jdbc_engine == 'mariadb' }}" driver_class: org.mariadb.jdbc.Driver - xa_datasource_class: org.mariadb.jdbc.MySQLDataSource + xa_datasource_class: org.mariadb.jdbc.MariaDbDataSource driver_module_name: "org.mariadb" driver_module_dir: "{{ keycloak_jboss_home }}/modules/org/mariadb/main" driver_version: "{{ keycloak_jdbc_driver_version }}" @@ -100,4 +100,4 @@ keycloak_remotecache: server_name: "{{ keycloak_infinispan_url }}" use_ssl: "{{ keycloak_infinispan_use_ssl }}" trust_store_path: "{{ keycloak_infinispan_trust_store_path }}" - trust_store_password: "{{ keycloak_infinispan_trust_store_password }}" \ No newline at end of file + trust_store_password: "{{ keycloak_infinispan_trust_store_password }}" From 623db426e0ebfea43724dcb136a67766740c2f30 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 31 May 2023 16:41:57 +0200 Subject: [PATCH 027/376] Keycloak: add feature enabling/disabling --- roles/keycloak/README.md | 1 + roles/keycloak/defaults/main.yml | 2 ++ roles/keycloak/meta/argument_specs.yml | 9 +++++++-- roles/keycloak/tasks/install.yml | 12 ++++++++++++ .../templates/keycloak-profile.properties.j2 | 3 +++ roles/keycloak/vars/main.yml | 1 + 6 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 roles/keycloak/templates/keycloak-profile.properties.j2 diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 3fc8a61..adbc4cd 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -77,6 +77,7 @@ Role Defaults |`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` if `keycloak_service_restart_on_failure` else `` | |`keycloak_service_restartsec`| systemd RestartSec | `10s` if `keycloak_service_restart_on_failure` else `` | |`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` | +|`keycloak_features` | List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]` | `[]` |`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` | |`keycloak_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path | `None` | |`keycloak_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index aa52d74..78b626d 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -16,6 +16,7 @@ keycloak_config_dir: "{{ keycloak_jboss_home }}/standalone/configuration" keycloak_config_standalone_xml: "keycloak.xml" keycloak_config_path_to_standalone_xml: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}" keycloak_config_override_template: '' +keycloak_config_path_to_properties: "{{ keycloak_jboss_home }}/standalone/configuration/profile.properties" keycloak_service_user: keycloak keycloak_service_group: keycloak keycloak_service_pidfile: "/run/keycloak.pid" @@ -45,6 +46,7 @@ keycloak_management_http_port: 9990 keycloak_management_https_port: 9993 keycloak_java_opts: "-Xms1024m -Xmx2048m" keycloak_prefer_ipv4: True +keycloak_features: [] ### Enable configuration for database backend, clustering and remote caches on infinispan keycloak_ha_enabled: False diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 0dc4cb3..1c03cbd 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -89,6 +89,11 @@ argument_specs: default: "/run/keycloak.pid" description: "PID file path for service" type: "str" + keycloak_features: + # line 17 of keycloak/defaults/main.yml + default: "[]" + description: "List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]`" + type: "list" keycloak_bind_address: # line 34 of keycloak/defaults/main.yml default: "0.0.0.0" @@ -96,7 +101,7 @@ argument_specs: type: "str" keycloak_management_port_bind_address: default: "127.0.0.1" - description: "Address for binding the managemnt ports" + description: "Address for binding the management ports" type: "str" keycloak_host: # line 35 of keycloak/defaults/main.yml @@ -318,7 +323,7 @@ argument_specs: default: "{{ True if keycloak_ha_enabled else False }}" description: "Enable remote cache store when in clustered ha configurations" type: "bool" - keycloak_db_background_validation: + keycloak_db_background_validation: default: False description: "Enable background validation of database connection" type: "bool" diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index f9c9028..b3294f4 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -268,3 +268,15 @@ - keycloak_ha_enabled - keycloak_remote_cache_enabled - keycloak_config_override_template | length == 0 + +- name: "Deploy profile.properties file to {{ keycloak_config_path_to_properties }}" + become: yes + ansible.builtin.template: + src: keycloak-profile.properties.j2 + dest: "{{ keycloak_config_path_to_properties }}" + owner: "{{ keycloak_service_user }}" + group: "{{ keycloak_service_group }}" + mode: 0640 + notify: + - restart keycloak + when: keycloak_features | length > 0 diff --git a/roles/keycloak/templates/keycloak-profile.properties.j2 b/roles/keycloak/templates/keycloak-profile.properties.j2 new file mode 100644 index 0000000..c618dc2 --- /dev/null +++ b/roles/keycloak/templates/keycloak-profile.properties.j2 @@ -0,0 +1,3 @@ +{% for feature in keycloak.features %} +feature.{{ feature.name }}={{ feature.status | default('enabled') }} +{% endfor %} \ No newline at end of file diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 638ed3d..4798545 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -14,6 +14,7 @@ keycloak: health_url: "{{ keycloak_management_url }}/health" cli_path: "{{ keycloak_jboss_home }}/bin/jboss-cli.sh" config_template_source: "{{ keycloak_config_override_template if keycloak_config_override_template | length > 0 else 'standalone-ha.xml.j2' if keycloak_remote_cache_enabled else 'standalone.xml.j2' }}" + features: "{{ keycloak_features }}" # database keycloak_jdbc: From bc4cb5c52ad9a8e3724869f79da5adc97eedba00 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 31 May 2023 18:11:00 +0200 Subject: [PATCH 028/376] Introduce `keycloak_service_restart_always` alongside `keycloak_service_restart_on_failure` --- roles/keycloak/README.md | 9 +++++---- roles/keycloak/defaults/main.yml | 9 +++++---- roles/keycloak/meta/argument_specs.yml | 8 ++++++-- roles/keycloak/templates/keycloak.service.j2 | 8 ++++---- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index adbc4cd..ef6cc01 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -72,10 +72,11 @@ Role Defaults |`keycloak_config_standalone_xml`| filename for configuration | `keycloak.xml` | |`keycloak_service_user`| posix account username | `keycloak` | |`keycloak_service_group`| posix account group | `keycloak` | -|`keycloak_service_restart_on_failure`| systemd restart-on-failure behavior activation |True -|`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` if `keycloak_service_restart_on_failure` else `` | -|`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` if `keycloak_service_restart_on_failure` else `` | -|`keycloak_service_restartsec`| systemd RestartSec | `10s` if `keycloak_service_restart_on_failure` else `` | +|`keycloak_service_restart_always`| systemd restart always behavior activation | `False` +|`keycloak_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` +|`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` | +|`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` | +|`keycloak_service_restartsec`| systemd RestartSec | `10s` | |`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` | |`keycloak_features` | List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]` | `[]` |`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 78b626d..d0137a8 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -24,10 +24,11 @@ keycloak_service_name: keycloak keycloak_service_desc: Keycloak keycloak_service_start_delay: 10 keycloak_service_start_retries: 25 -keycloak_service_restart_on_failure: True -keycloak_service_startlimitintervalsec: "{{ 300 if keycloak_service_restart_on_failure else '' }}" -keycloak_service_startlimitburst: "{{ 5 if keycloak_service_restart_on_failure else '' }}" -keycloak_service_restartsec: "{{ '10s' if keycloak_service_restart_on_failure else '' }}" +keycloak_service_restart_always: False +keycloak_service_restart_on_failure: False +keycloak_service_startlimitintervalsec: "300" +keycloak_service_startlimitburst: "5" +keycloak_service_restartsec: "10s" keycloak_configure_firewalld: False diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 1c03cbd..8e05939 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -299,9 +299,13 @@ argument_specs: default: "25" description: "How many time should Ansible retry to connect to the service after it was started, before failing." type: "int" + keycloak_service_restart_always: + default: false + description: "systemd restart always behavior activation for keycloak" + type: "bool" keycloak_service_restart_on_failure: - default: true - description: "systemd restart-on-failure behavior activation for keycloak" + default: false + description: "systemd restart on-failure behavior activation for keycloak" type: "bool" keycloak_service_startlimitintervalsec: default: 300 diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index 0dec52a..5de014b 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -2,10 +2,8 @@ [Unit] Description={{ keycloak.service_name }} Server After=network.target -{% if keycloak_service_restart_on_failure %} StartLimitIntervalSec={{ keycloak_service_startlimitintervalsec }} StartLimitBurst={{ keycloak_service_startlimitburst }} -{% endif %} [Service] @@ -17,10 +15,12 @@ ExecStop={{ keycloak_dest }}/keycloak-service.sh stop TimeoutStartSec=30 TimeoutStopSec=30 LimitNOFILE=102642 -{% if keycloak_service_restart_on_failure %} +{% if keycloak_service_restart_always %} +Restart=always +{% elif keycloak_service_restart_on_failure %} Restart=on-failure -RestartSec={{ keycloak_service_restartsec }} {% endif %} +RestartSec={{ keycloak_service_restartsec }} [Install] WantedBy=multi-user.target From 6986190159d5a2dd12b89b1665746d5f25d854ca Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 1 Jun 2023 10:27:46 +0200 Subject: [PATCH 029/376] Bumo to v1.2.6 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 76205f1..d6ed1ac 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.5" +version: "1.2.6" readme: README.md authors: - Romain Pelisse From ced4ce7828ae0ddd62b9385423d68c7c0f6a07a5 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 7 Jun 2023 11:56:12 +0200 Subject: [PATCH 030/376] handle WFLYCTL0117 when validation_millis is 0 --- roles/keycloak/templates/standalone-ha.xml.j2 | 2 ++ roles/keycloak/templates/standalone-infinispan.xml.j2 | 2 ++ roles/keycloak/templates/standalone.xml.j2 | 2 ++ 3 files changed, 6 insertions(+) diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 67f5da8..e3b62ea 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -139,8 +139,10 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} {{ keycloak_db_background_validate_on_match }} +{% if keycloak_db_background_validation_millis > 0 or keycloak_db_background_validation %} {{ keycloak_db_background_validation }} {{ keycloak_db_background_validation_millis }} +{% endif %} {% else %} jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index cea9c87..c1590cd 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -139,8 +139,10 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} {{ keycloak_db_background_validate_on_match }} +{% if keycloak_db_background_validation_millis > 0 or keycloak_db_background_validation %} {{ keycloak_db_background_validation }} {{ keycloak_db_background_validation_millis }} +{% endif %} {% else %} jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index e38e1f0..4e5aa05 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -126,8 +126,10 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} {{ keycloak_db_background_validate_on_match }} +{% if keycloak_db_background_validation_millis > 0 or keycloak_db_background_validation %} {{ keycloak_db_background_validation }} {{ keycloak_db_background_validation_millis }} +{% endif %} {% else %} jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE From e99a0db174886fe72d832183e1aea0e9f424191d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 7 Jun 2023 12:25:58 +0200 Subject: [PATCH 031/376] Add missing type conversion in templates --- roles/keycloak/templates/standalone-ha.xml.j2 | 2 +- roles/keycloak/templates/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/standalone.xml.j2 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index e3b62ea..f108d2d 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -139,7 +139,7 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} {{ keycloak_db_background_validate_on_match }} -{% if keycloak_db_background_validation_millis > 0 or keycloak_db_background_validation %} +{% if keycloak_db_background_validation_millis | int > 0 or keycloak_db_background_validation %} {{ keycloak_db_background_validation }} {{ keycloak_db_background_validation_millis }} {% endif %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index c1590cd..0d052ed 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -139,7 +139,7 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} {{ keycloak_db_background_validate_on_match }} -{% if keycloak_db_background_validation_millis > 0 or keycloak_db_background_validation %} +{% if keycloak_db_background_validation_millis | int > 0 or keycloak_db_background_validation %} {{ keycloak_db_background_validation }} {{ keycloak_db_background_validation_millis }} {% endif %} diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 4e5aa05..bf2d528 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -126,7 +126,7 @@ {{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }} {{ keycloak_db_background_validate_on_match }} -{% if keycloak_db_background_validation_millis > 0 or keycloak_db_background_validation %} +{% if keycloak_db_background_validation_millis | int > 0 or keycloak_db_background_validation %} {{ keycloak_db_background_validation }} {{ keycloak_db_background_validation_millis }} {% endif %} From 97bea7ba394d833eff05ab72b9010dd957223ca5 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 7 Jun 2023 12:29:15 +0000 Subject: [PATCH 032/376] Update changelog for release 1.2.6 --- CHANGELOG.rst | 15 +++++++++++++++ changelogs/changelog.yaml | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 87d2470..620d281 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,21 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.2.6 +====== + +Minor Changes +------------- + +- Add profile features enabling/disabling `#87 `_ +- Improve service restart behavior configuration `#88 `_ +- Update default xa_datasource_class value for mariadb jdbc configuration `#89 `_ + +Bugfixes +-------- + +- Handle WFLYCTL0117 when background validation millis is 0 `#90 `_ + v1.2.5 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 779b2bd..203f4f2 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -224,3 +224,26 @@ releases: - 85.yaml - 86.yaml release_date: '2023-05-26' + 1.2.6: + changes: + bugfixes: + - 'Handle WFLYCTL0117 when background validation millis is 0 `#90 `_ + + ' + minor_changes: + - 'Add profile features enabling/disabling `#87 `_ + + ' + - 'Improve service restart behavior configuration `#88 `_ + + ' + - 'Update default xa_datasource_class value for mariadb jdbc configuration `#89 + `_ + + ' + fragments: + - 87.yaml + - 88.yaml + - 89.yaml + - 90.yaml + release_date: '2023-06-07' From 874215a5920b9a14f9f4f22579098cf6df01d9a9 Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Fri, 9 Jun 2023 10:51:13 +0200 Subject: [PATCH 033/376] remove empty string default for keycloak_db_valid_conn_sql rely on defaults set in keycloak_jdbc dict --- roles/keycloak/defaults/main.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index d0137a8..4a1fda3 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -97,8 +97,6 @@ keycloak_db_pass: keycloak-pass keycloak_db_background_validation: False keycloak_db_background_validation_millis: "{{ 10000 if keycloak_db_background_validation else 0 }}" keycloak_db_background_validate_on_match: False -# variable to override database connection validation query -keycloak_db_valid_conn_sql: keycloak_jdbc_url: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].url }}" keycloak_jdbc_driver_version: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].version }}" # override the variables above, following defaults show minimum supported versions From 18e60daa93496ffdfb65944155d9a42116d9e5d4 Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Sat, 10 Jun 2023 15:16:58 +0200 Subject: [PATCH 034/376] Update Keycloakx to v21.1.1 Signed-off-by: footur <3769085+Footur@users.noreply.github.com> --- roles/keycloak_quarkus/defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 371180e..063863f 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 18.0.0 +keycloak_quarkus_version: 21.1.1 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From 33404281942d0220cb44408b311dacf1442d98cb Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Sat, 10 Jun 2023 15:18:31 +0200 Subject: [PATCH 035/376] =?UTF-8?q?Remove=20the=20"--auto-build"=20flag=20?= =?UTF-8?q?=E2=80=93=20it's=20deprecated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: footur <3769085+Footur@users.noreply.github.com> --- roles/keycloak_quarkus/templates/keycloak.service.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 14e7542..f7ffc1c 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -10,7 +10,7 @@ PIDFile={{ keycloak_quarkus_service_pidfile }} {% if keycloak_quarkus_start_dev %} ExecStart={{ keycloak.home }}/bin/kc.sh start-dev {% else %} -ExecStart={{ keycloak.home }}/bin/kc.sh start --auto-build --log={{ keycloak_quarkus_log }} +ExecStart={{ keycloak.home }}/bin/kc.sh start --log={{ keycloak_quarkus_log }} {% endif %} User={{ keycloak.service_user }} From 1dd579a6d1b52f64179140d842194fc07fd683b4 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Sat, 10 Jun 2023 16:31:19 +0200 Subject: [PATCH 036/376] Allow to override jgroups subnet --- roles/keycloak/README.md | 2 +- roles/keycloak/defaults/main.yml | 1 + roles/keycloak/meta/argument_specs.yml | 4 ++++ roles/keycloak/templates/standalone-ha.xml.j2 | 4 +++- roles/keycloak/templates/standalone-infinispan.xml.j2 | 4 +++- 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index ef6cc01..f25420f 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -165,7 +165,7 @@ The following variables are _optional_: |:---------|:------------| |`keycloak_db_valid_conn_sql` | Override the default database connection validation query sql | |`keycloak_admin_url` | Override the default administration endpoint URL | - +|`keycloak_jgroups_subnet`| Override the subnet match for jgroups cluster formation; if not defined, it will be inferred from local machine route configuration | Example Playbook ----------------- diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index d0137a8..da98d24 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -42,6 +42,7 @@ keycloak_http_port: 8080 keycloak_https_port: 8443 keycloak_ajp_port: 8009 keycloak_jgroups_port: 7600 +keycloak_jgroups_subnet: keycloak_management_port_bind_address: 127.0.0.1 keycloak_management_http_port: 9990 keycloak_management_https_port: 9993 diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 8e05939..5392cfc 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -347,6 +347,10 @@ argument_specs: required: False description: "Override the default administration endpoint URL" type: "str" + keycloak_jgroups_subnet: + required: False + description: "Override the subnet match for jgroups cluster formation; if not defined, it will be inferred from local machine route configuration" + type: "str" downstream: options: sso_version: diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index f108d2d..f3ca185 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -662,7 +662,9 @@ -{% if ansible_default_ipv4 is defined %} +{% keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} + +{% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} {% else %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 0d052ed..304b0fd 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -700,7 +700,9 @@ -{% if ansible_default_ipv4 is defined %} +{% keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} + +{% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} {% else %} From 8f697f6a536c5253a9bd6a62720b12181f711b05 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Sat, 10 Jun 2023 16:45:13 +0200 Subject: [PATCH 037/376] Bump to 1.2.7 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index d6ed1ac..f69fa39 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.6" +version: "1.2.7" readme: README.md authors: - Romain Pelisse From 14e7b402b792cb5e12ad5cb9cbd4948f4649c542 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Sat, 10 Jun 2023 18:37:58 +0200 Subject: [PATCH 038/376] fix typo in templates --- roles/keycloak/templates/standalone-ha.xml.j2 | 2 +- roles/keycloak/templates/standalone-infinispan.xml.j2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index f3ca185..226da6e 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -662,7 +662,7 @@ -{% keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} +{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} {% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 304b0fd..f7df743 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -700,7 +700,7 @@ -{% keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} +{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} {% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} From 7ec695ee15e2df488528fda5062d79213a7d469e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Sat, 10 Jun 2023 19:26:46 +0200 Subject: [PATCH 039/376] Fix wrong task message --- roles/keycloak/tasks/install.yml | 2 +- roles/keycloak/templates/standalone-ha.xml.j2 | 4 ++-- roles/keycloak/templates/standalone-infinispan.xml.j2 | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index b3294f4..581db9f 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -239,7 +239,7 @@ loop: "{{ ansible_play_batch }}" when: keycloak_ha_enabled and keycloak_ha_discovery == 'TCPPING' -- name: "Deploy HA {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak.config_template_source }}" +- name: "Deploy HA {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}" become: yes ansible.builtin.template: src: templates/standalone-ha.xml.j2 diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 226da6e..893ec0d 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -662,8 +662,8 @@ -{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} - +{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | string | length > 0 %} + {% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} {% else %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index f7df743..a030de0 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -700,8 +700,8 @@ -{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | length > 0 %} - +{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | string | length > 0 %} + {% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} {% else %} From 83525dbed0a5ee71ab74a33366dac232b8747179 Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 16 Jun 2023 10:15:59 +0200 Subject: [PATCH 040/376] Update the Keycloakx version in Molecule --- molecule/quarkus/prepare.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 4b85c14..f18574b 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -30,13 +30,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-18.0.0/conf/ + path: /opt/keycloak/keycloak-21.1.1/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-18.0.0/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-21.1.1/conf/{{ item }}" mode: 0444 loop: - cert.pem From fc6e00974dfcc00482b9e9e7073be336480194ce Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 16 Jun 2023 10:19:31 +0200 Subject: [PATCH 041/376] Define the varbosity of Ansible in Molecule --- molecule/default/molecule.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index 6f3b9c7..81dee05 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -34,6 +34,7 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" + ANSIBLE_VERBOSITY: 3 verifier: name: ansible scenario: From 5f1f8b57623939b5d46e71872d85ce9075a4149e Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Sat, 17 Jun 2023 12:47:27 +0200 Subject: [PATCH 042/376] [CI] Use ansible-lint in v6.17.0 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3764e8f..92b530f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: - name: Install yamllint, ansible and molecule run: | python -m pip install --upgrade pip - pip install yamllint 'molecule[docker]~=3.5.2' ansible-core flake8 ansible-lint voluptuous + pip install yamllint 'molecule[docker]~=3.5.2' ansible-core flake8 ansible-lint==6.17.0 voluptuous pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt - name: Create default collection path From 926353f395fa48a57db5c816e002e7abb5e43ef6 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Jun 2023 16:41:35 +0200 Subject: [PATCH 043/376] add certified collection notice --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 608d253..7c54a51 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ [![Build Status](https://github.com/ansible-middleware/keycloak/workflows/CI/badge.svg?branch=main)](https://github.com/ansible-middleware/keycloak/actions/workflows/ci.yml) +If you are Red Hat customer, install `redhat.sso` from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection. + Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on). From cebec9c717b6fc55402d9098d53236de15f3b164 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 19 Jun 2023 15:23:06 +0000 Subject: [PATCH 044/376] Update changelog for release 1.2.7 --- CHANGELOG.rst | 9 +++++++++ changelogs/changelog.yaml | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 620d281..566fc60 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,15 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.2.7 +====== + +Minor Changes +------------- + +- Allow to override jgroups subnet `#93 `_ +- keycloak-quarkus: update keycloakx to v21.1.1 `#92 `_ + v1.2.6 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 203f4f2..b6e6bd1 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -247,3 +247,16 @@ releases: - 89.yaml - 90.yaml release_date: '2023-06-07' + 1.2.7: + changes: + minor_changes: + - 'Allow to override jgroups subnet `#93 `_ + + ' + - 'keycloak-quarkus: update keycloakx to v21.1.1 `#92 `_ + + ' + fragments: + - 92.yaml + - 93.yaml + release_date: '2023-06-19' From a82e654cc4243d380832e7cec3a00f87bcff70ed Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 19 Jun 2023 17:26:15 +0200 Subject: [PATCH 045/376] Bump to 1.2.8 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index f69fa39..a2eeccb 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.7" +version: "1.2.8" readme: README.md authors: - Romain Pelisse From fae30797514a1533c650ab28bd103eb04829d27b Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Fri, 23 Jun 2023 11:40:15 +0200 Subject: [PATCH 046/376] Fix #97 - proper checks for keycloak_jgroups_subnet --- roles/keycloak/templates/standalone-ha.xml.j2 | 2 +- roles/keycloak/templates/standalone-infinispan.xml.j2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 893ec0d..98e26f6 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -662,7 +662,7 @@ -{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | string | length > 0 %} +{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet is not none and keycloak_jgroups_subnet | string | length > 0 %} {% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index a030de0..38fbfec 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -700,7 +700,7 @@ -{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet | string | length > 0 %} +{% if keycloak_jgroups_subnet is defined and keycloak_jgroups_subnet is not none and keycloak_jgroups_subnet | string | length > 0 %} {% elif ansible_default_ipv4 is defined and (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') | length > 0 %} From 26a9249d0787806e821d5018b740a8015f022c99 Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 23 Jun 2023 12:32:35 +0200 Subject: [PATCH 047/376] Update the Keycloakx version in the README --- roles/keycloak_quarkus/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index ab98d4a..7460130 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -1,7 +1,7 @@ keycloak_quarkus ================ -Install [keycloak](https://keycloak.org/) >= 17.0.0 (quarkus) server configurations. +Install [keycloak](https://keycloak.org/) >= 21.1.1 (quarkus) server configurations. Role Defaults @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `17.0.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `21.1.1` | * Service configuration @@ -71,7 +71,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `17.0.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `21.1.1` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | From 7c4d420fead16cb1c84dddf8c74c6fb093fdfa26 Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 14 Jul 2023 11:36:54 +0200 Subject: [PATCH 048/376] Update Keycloak to version 22.0.0 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 6 +++--- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index f18574b..9fd6041 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -30,13 +30,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-21.1.1/conf/ + path: /opt/keycloak/keycloak-22.0.0/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-21.1.1/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-22.0.0/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 7460130..f8b8b60 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -1,7 +1,7 @@ keycloak_quarkus ================ -Install [keycloak](https://keycloak.org/) >= 21.1.1 (quarkus) server configurations. +Install [keycloak](https://keycloak.org/) >= 22.0.0 (quarkus) server configurations. Role Defaults @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `21.1.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.0` | * Service configuration @@ -71,7 +71,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `21.1.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.0` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 063863f..75125e2 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 21.1.1 +keycloak_quarkus_version: 22.0.0 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From f195d164d14918114e8fbca92cff836e88870fba Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 14 Jul 2023 13:21:27 +0200 Subject: [PATCH 049/376] Enable Ansible verbosity in the CI test --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92b530f..08bbd64 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,3 +56,4 @@ jobs: env: PY_COLORS: '1' ANSIBLE_FORCE_COLOR: '1' + ANSIBLE_VERBOSITY: '1' From 8738240a24c8576c42e2c413e6ad655866dfdf7c Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 28 Jul 2023 09:57:37 +0200 Subject: [PATCH 050/376] docs: add missing param in defaults comment --- roles/keycloak_realm/defaults/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/keycloak_realm/defaults/main.yml b/roles/keycloak_realm/defaults/main.yml index e1caeec..17112d5 100644 --- a/roles/keycloak_realm/defaults/main.yml +++ b/roles/keycloak_realm/defaults/main.yml @@ -32,6 +32,7 @@ keycloak_admin_password: '' # realm: "{{ keycloak_realm }}" # public_client: "{{ keycloak_client_public }}" # web_origins: "{{ keycloak_client_web_origins }}" +# redirect_uris: "{{ keycloak_client_redirect_uris }}" # users: "{{ keycloak_client_users }}" keycloak_clients: [] From 7fea211639d23e9a4db49c110e5c7a62b87d6f7a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 31 Jul 2023 08:38:36 +0200 Subject: [PATCH 051/376] ci: update molecule --- .github/workflows/ci.yml | 22 +++++++++++++++++++--- README.md | 2 +- molecule/default/molecule.yml | 9 --------- molecule/overridexml/molecule.yml | 9 --------- molecule/quarkus/molecule.yml | 9 --------- 5 files changed, 20 insertions(+), 31 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92b530f..fa060f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,8 @@ on: branches: - main pull_request: + schedule: + - cron: '0 6 * * *' env: COLORTERM: 'yes' @@ -16,7 +18,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python_version: ["3.10"] + python_version: ["3.11"] steps: - name: Check out code uses: actions/checkout@v2 @@ -32,8 +34,16 @@ jobs: - name: Install yamllint, ansible and molecule run: | python -m pip install --upgrade pip - pip install yamllint 'molecule[docker]~=3.5.2' ansible-core flake8 ansible-lint==6.17.0 voluptuous - pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt + pip install yamllint 'molecule>=4.0.4' 'molecule-plugins[docker]>=23.0.0' ansible-core flake8 ansible-lint voluptuous + if [ -f ansible_collections/middleware_automation/keycloak/requirements.txt ]; then + pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt + fi + if [ -f ansible_collections/middleware_automation/keycloak/requirements.yml ]; then + ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/requirements.yml -p /home/runner/.ansible/collections --force-with-deps + fi + if [ -f ansible_collections/middleware_automation/keycloak/molecule/requirements.yml ]; then + ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/molecule/requirements.yml -p /home/runner/.ansible/collections + fi - name: Create default collection path run: | @@ -46,6 +56,12 @@ jobs: repository: ansible-middleware/ansible-lint-custom-rules path: ansible_collections/ansible-lint-custom-rules/ + - name: Run linter + run: | + ansible-lint --version + ansible-lint -v + working-directory: ./ansible_collections/middleware_automation/amq + - name: Run sanity tests run: ansible-test sanity -v --color --python ${{ matrix.python_version }} --exclude changelogs/fragments/.gitignore --skip-test symlinks working-directory: ./ansible_collections/middleware_automation/keycloak diff --git a/README.md b/README.md index 7c54a51..9ae661e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Build Status](https://github.com/ansible-middleware/keycloak/workflows/CI/badge.svg?branch=main)](https://github.com/ansible-middleware/keycloak/actions/workflows/ci.yml) -If you are Red Hat customer, install `redhat.sso` from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection. +> **_NOTE:_ If you are Red Hat customer, install `redhat.sso` from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection.** Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on). diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index 81dee05..abdc729 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -1,12 +1,6 @@ --- -dependency: - name: shell - command: ansible-galaxy collection install -r molecule/requirements.yml -p $HOME/.ansible/collections --force-with-deps driver: name: docker -lint: | - ansible-lint --version - ansible-lint -v platforms: - name: instance image: registry.access.redhat.com/ubi8/ubi-init:latest @@ -39,11 +33,8 @@ verifier: name: ansible scenario: test_sequence: - - dependency - - lint - cleanup - destroy - - syntax - create - prepare - converge diff --git a/molecule/overridexml/molecule.yml b/molecule/overridexml/molecule.yml index 6f3b9c7..c133eee 100644 --- a/molecule/overridexml/molecule.yml +++ b/molecule/overridexml/molecule.yml @@ -1,12 +1,6 @@ --- -dependency: - name: shell - command: ansible-galaxy collection install -r molecule/requirements.yml -p $HOME/.ansible/collections --force-with-deps driver: name: docker -lint: | - ansible-lint --version - ansible-lint -v platforms: - name: instance image: registry.access.redhat.com/ubi8/ubi-init:latest @@ -38,11 +32,8 @@ verifier: name: ansible scenario: test_sequence: - - dependency - - lint - cleanup - destroy - - syntax - create - prepare - converge diff --git a/molecule/quarkus/molecule.yml b/molecule/quarkus/molecule.yml index 3895a53..c04e300 100644 --- a/molecule/quarkus/molecule.yml +++ b/molecule/quarkus/molecule.yml @@ -1,12 +1,6 @@ --- -dependency: - name: shell - command: ansible-galaxy collection install -r molecule/requirements.yml -p $HOME/.ansible/collections --force-with-deps driver: name: docker -lint: | - ansible-lint --version - ansible-lint -v platforms: - name: instance image: registry.access.redhat.com/ubi8/ubi-init:latest @@ -40,11 +34,8 @@ verifier: name: ansible scenario: test_sequence: - - dependency - - lint - cleanup - destroy - - syntax - create - prepare - converge From 5385fbb8e9888af635fe8d8230739237a7477f00 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 31 Jul 2023 08:40:17 +0200 Subject: [PATCH 052/376] ci: update molecule --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fa060f7..05bee8c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,7 @@ jobs: run: | ansible-lint --version ansible-lint -v - working-directory: ./ansible_collections/middleware_automation/amq + working-directory: ./ansible_collections/middleware_automation/keycloak - name: Run sanity tests run: ansible-test sanity -v --color --python ${{ matrix.python_version }} --exclude changelogs/fragments/.gitignore --skip-test symlinks From f400a5bbf80bad197ad9fafb5900e96b65e05b6f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 31 Jul 2023 09:01:54 +0200 Subject: [PATCH 053/376] fix_java_11_tzdata --- roles/keycloak/tasks/prereqs.yml | 3 ++- roles/keycloak_quarkus/tasks/prereqs.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index 418a574..02370c7 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -43,4 +43,5 @@ - "{{ keycloak_jvm_package }}" - unzip - procps-ng - - initscripts \ No newline at end of file + - initscripts + - tzdata-java diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index c0201b3..4040d8f 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -22,4 +22,5 @@ - "{{ keycloak_quarkus_jvm_package }}" - unzip - procps-ng - - initscripts \ No newline at end of file + - initscripts + - tzdata-java From 79335927252e56ac57db2fcd57efa19d6b2f7adb Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 31 Jul 2023 09:19:47 +0200 Subject: [PATCH 054/376] Revert README.md --- roles/keycloak_quarkus/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index f8b8b60..cd5383f 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -1,7 +1,7 @@ keycloak_quarkus ================ -Install [keycloak](https://keycloak.org/) >= 22.0.0 (quarkus) server configurations. +Install [keycloak](https://keycloak.org/) >= 20.0.0 (quarkus) server configurations. Role Defaults From 84d6e7baca786bab4930767cc50f9de53297ef54 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 31 Jul 2023 10:29:28 +0200 Subject: [PATCH 055/376] set java-17 for keycloak_quarkus --- .github/workflows/ci.yml | 6 +++++- roles/keycloak/tasks/systemd.yml | 13 ++++--------- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/tasks/systemd.yml | 13 ++++--------- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4c1b87..c22fd4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,10 @@ jobs: strategy: matrix: python_version: ["3.11"] + molecule_test: + - default + - quarkus + - overridexml steps: - name: Check out code uses: actions/checkout@v2 @@ -67,7 +71,7 @@ jobs: working-directory: ./ansible_collections/middleware_automation/keycloak - name: Run molecule test - run: molecule test --all + run: molecule test -s ${{ matrix.molecule_test }} working-directory: ./ansible_collections/middleware_automation/keycloak env: PY_COLORS: '1' diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index 871180f..4b24822 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -10,14 +10,9 @@ notify: - restart keycloak -- name: Determine JAVA_HOME for selected JVM RPM # noqa blocked_modules - ansible.builtin.shell: | - set -o pipefail - rpm -ql {{ keycloak_jvm_package }} | grep -Po '/usr/lib/jvm/.*(?=/bin/java$)' - args: - executable: /bin/bash - changed_when: False - register: rpm_java_home +- name: Determine JAVA_HOME for selected JVM RPM + ansible.builtin.set_fact: + rpm_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" - name: "Configure sysconfig file for {{ keycloak.service_name }} service" become: yes @@ -28,7 +23,7 @@ group: root mode: 0644 vars: - keycloak_rpm_java_home: "{{ rpm_java_home.stdout }}" + keycloak_rpm_java_home: "{{ rpm_java_home }}" notify: - restart keycloak diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 75125e2..53a9c76 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -9,7 +9,7 @@ keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_q keycloak_quarkus_offline_install: False ### Install location and service settings -keycloak_quarkus_jvm_package: java-11-openjdk-headless +keycloak_quarkus_jvm_package: java-17-openjdk-headless keycloak_quarkus_java_home: keycloak_quarkus_dest: /opt/keycloak keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index ee8a1cc..c0be72b 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -1,12 +1,7 @@ --- -- name: Determine JAVA_HOME for selected JVM RPM # noqa blocked_modules - ansible.builtin.shell: | - set -o pipefail - rpm -ql {{ keycloak_quarkus_jvm_package }} | grep -Po '/usr/lib/jvm/.*(?=/bin/java$)' - args: - executable: /bin/bash - changed_when: False - register: rpm_java_home +- name: Determine JAVA_HOME for selected JVM RPM + ansible.builtin.set_fact: + rpm_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" - name: "Configure sysconfig file for keycloak service" become: yes @@ -17,7 +12,7 @@ group: root mode: 0644 vars: - keycloak_rpm_java_home: "{{ rpm_java_home.stdout }}" + keycloak_rpm_java_home: "{{ rpm_java_home }}" notify: - restart keycloak From 5b0112384676ad5999a26c4efca068956f12a844 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 31 Jul 2023 10:39:47 +0200 Subject: [PATCH 056/376] fix verify for molecule default scenario --- molecule/default/verify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 490b38c..92a245e 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -17,7 +17,7 @@ - name: Verify we are running on requested jvm # noqa blocked_modules command-instead-of-module ansible.builtin.shell: | set -o pipefail - ps -ef | grep /usr/lib/jvm/java-11 | grep -v grep + ps -ef | grep '/etc/alternatives/jre_11/' | grep -v grep args: executable: /bin/bash changed_when: no From db0aafd465ed7b98d2f4d6c86cf8d78dffbee1b4 Mon Sep 17 00:00:00 2001 From: Joel <34544090+JoelKle@users.noreply.github.com> Date: Tue, 8 Aug 2023 11:05:25 +0200 Subject: [PATCH 057/376] Update bindep.txt to support RHEL9 On RHEL9 the rpm package `python39-devel` doesn't exists. The real name is `python3-devel`. --- bindep.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bindep.txt b/bindep.txt index 641ec85..840876b 100644 --- a/bindep.txt +++ b/bindep.txt @@ -1,4 +1,5 @@ -python39-devel [platform:rpm compile] +python3-devel [compile platform:rpm] +python39-devel [compile platform:centos-8 platform:rhel-8] git-lfs [platform:rpm] python3-netaddr [platform:rpm] python3-lxml [platform:rpm] From 07b1c514bb4432e8dd0ba607c0c1f86f5634df90 Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Tue, 8 Aug 2023 16:52:23 +0200 Subject: [PATCH 058/376] Add User and Group directives in systemd unit file --- roles/keycloak/templates/keycloak.service.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index 5de014b..8a94c62 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -8,6 +8,8 @@ StartLimitBurst={{ keycloak_service_startlimitburst }} [Service] Type=forking +User={{ keycloak_service_user }} +Group={{ keycloak_service_group }} EnvironmentFile=-/etc/sysconfig/keycloak PIDFile={{ keycloak_service_pidfile }} ExecStart={{ keycloak_dest }}/keycloak-service.sh start From 91ec4116993fc6042d8756970184df7c17e20ccd Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Tue, 8 Aug 2023 17:49:43 +0200 Subject: [PATCH 059/376] create pidfile folder if needed --- roles/keycloak/tasks/install.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 581db9f..13f4ef3 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -53,6 +53,21 @@ group: "{{ keycloak_service_group }}" mode: 0750 +- name: Check pidfile folder + ansible.builtin.stat: + path: "{{ keycloak_service_pidfile | dirname }}" + register: keycloak_service_pidfile_stat +- name: Create pidfile folder + become: yes + become_user: root + ansible.builtin.file: + dest: "{{ keycloak_service_pidfile | dirname }}" + state: directory + owner: "{{ keycloak_service_user }}" + group: "{{ keycloak_service_group }}" + mode: "0750" + when: not keycloak_service_pidfile_stat.stat.exists + ## check remote archive - name: Set download archive path ansible.builtin.set_fact: From c8ebbe72d2c07dede02c981d3d4497834ce9a95d Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Tue, 8 Aug 2023 18:30:46 +0200 Subject: [PATCH 060/376] change default pidfile location Signed-off-by: Massimo Schiavon --- roles/keycloak/README.md | 2 +- roles/keycloak/defaults/main.yml | 2 +- roles/keycloak/meta/argument_specs.yml | 2 +- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index f25420f..aae309b 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -77,7 +77,7 @@ Role Defaults |`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` | |`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` | |`keycloak_service_restartsec`| systemd RestartSec | `10s` | -|`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` | +|`keycloak_service_pidfile`| pid file path for service | `/run/keycloak/keycloak.pid` | |`keycloak_features` | List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]` | `[]` |`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` | |`keycloak_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path | `None` | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index a139d92..156af46 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -19,7 +19,7 @@ keycloak_config_override_template: '' keycloak_config_path_to_properties: "{{ keycloak_jboss_home }}/standalone/configuration/profile.properties" keycloak_service_user: keycloak keycloak_service_group: keycloak -keycloak_service_pidfile: "/run/keycloak.pid" +keycloak_service_pidfile: "/run/keycloak/keycloak.pid" keycloak_service_name: keycloak keycloak_service_desc: Keycloak keycloak_service_start_delay: 10 diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 5392cfc..daba3ba 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -86,7 +86,7 @@ argument_specs: type: "str" keycloak_service_pidfile: # line 31 of keycloak/defaults/main.yml - default: "/run/keycloak.pid" + default: "/run/keycloak/keycloak.pid" description: "PID file path for service" type: "str" keycloak_features: diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 53a9c76..0989868 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -17,7 +17,7 @@ keycloak_quarkus_config_dir: "{{ keycloak_quarkus_home }}/conf" keycloak_quarkus_start_dev: False keycloak_quarkus_service_user: keycloak keycloak_quarkus_service_group: keycloak -keycloak_quarkus_service_pidfile: "/run/keycloak.pid" +keycloak_quarkus_service_pidfile: "/run/keycloak/keycloak.pid" keycloak_quarkus_configure_firewalld: False ### administrator console password diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 66e8adf..2986c0c 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -61,7 +61,7 @@ argument_specs: type: "str" keycloak_quarkus_service_pidfile: # line 18 of defaults/main.yml - default: "/run/keycloak.pid" + default: "/run/keycloak/keycloak.pid" description: "Pid file path for service" type: "str" keycloak_quarkus_configure_firewalld: From 52d9286ea331cde943703c80eae870a4b0120a71 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 24 Aug 2023 13:20:49 +0200 Subject: [PATCH 061/376] ci: update workflows --- .github/workflows/ci.yml | 110 +++++++++++++++++++++++++++++-------- .github/workflows/docs.yml | 4 +- docs/conf.py | 3 +- docs/requirements.txt | 1 + 4 files changed, 92 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c22fd4c..9a5105d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,18 +14,103 @@ env: PYTEST_ADDOPTS: '--color=yes' jobs: - ci: + linter: runs-on: ubuntu-latest strategy: matrix: python_version: ["3.11"] + ansible_version: ["2.15"] + steps: + - name: Check out code + uses: actions/checkout@v3 + with: + path: ansible_collections/middleware_automation/keycloak + + - name: Set up Python ${{ matrix.python_version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python_version }} + cache: 'pip' + + - name: Create default collection path + run: | + mkdir -p /home/runner/.ansible/ + ln -s ${{ github.workspace }} /home/runner/.ansible/collections + + - name: Install yamllint, ansible and dependencies + run: | + python -m pip install --upgrade pip + pip install yamllint ansible-core==${{ matrix.ansible_version }} ansible-lint + if [ -f ansible_collections/middleware_automation/keycloak/requirements.txt ]; then + pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt + fi + if [ -f ansible_collections/middleware_automation/keycloak/requirements.yml ]; then + ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/requirements.yml -p /home/runner/.ansible/collections --force-with-deps + fi + + - name: Install ansible-lint custom rules + uses: actions/checkout@v3 + with: + repository: ansible-middleware/ansible-lint-custom-rules + path: ansible-lint-custom-rules/ + + - name: Run linter + run: | + ansible-lint --version + ansible-lint -v + working-directory: ./ansible_collections/middleware_automation/keycloak + + sanity: + runs-on: ubuntu-latest + strategy: + matrix: + python_version: ["3.8", "3.9", "3.11"] + ansible_version: ["2.11", "2.15"] + exclude: + - python_version: "3.8" + ansible_version: "2.15" + - python_version: "3.9" + ansible_version: "2.15" + - python_version: "3.11" + ansible_version: "2.11" + steps: + - name: Check out code + uses: actions/checkout@v3 + with: + path: ansible_collections/middleware_automation/keycloak + + - name: Set up Python ${{ matrix.python_version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python_version }} + cache: 'pip' + + - name: Create default collection path + run: | + mkdir -p /home/runner/.ansible/ + ln -s ${{ github.workspace }} /home/runner/.ansible/collections + + - name: Install ansible-core stable-${{ matrix.ansible_version }} + run: | + pip install https://github.com/ansible/ansible/archive/stable-${{ matrix.ansible_version }}.tar.gz --disable-pip-version-check + + - name: Run sanity tests + run: ansible-test sanity -v --color --docker --python ${{ matrix.python_version }} --exclude docs/conf.py --exclude changelogs/fragments/.gitignore --skip-test symlinks + working-directory: ./ansible_collections/middleware_automation/keycloak + + molecule: + runs-on: ubuntu-latest + strategy: + matrix: + python_version: ["3.11"] + ansible_version: ["2.14", "2.15"] molecule_test: - default - quarkus - overridexml steps: - name: Check out code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: ansible_collections/middleware_automation/keycloak @@ -49,27 +134,6 @@ jobs: ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/molecule/requirements.yml -p /home/runner/.ansible/collections fi - - name: Create default collection path - run: | - mkdir -p /home/runner/.ansible/ - ln -s /home/runner/work/keycloak/keycloak /home/runner/.ansible/collections - - - name: Install ansible-lint custom rules - uses: actions/checkout@v2 - with: - repository: ansible-middleware/ansible-lint-custom-rules - path: ansible_collections/ansible-lint-custom-rules/ - - - name: Run linter - run: | - ansible-lint --version - ansible-lint -v - working-directory: ./ansible_collections/middleware_automation/keycloak - - - name: Run sanity tests - run: ansible-test sanity -v --color --python ${{ matrix.python_version }} --exclude changelogs/fragments/.gitignore --skip-test symlinks - working-directory: ./ansible_collections/middleware_automation/keycloak - - name: Run molecule test run: molecule test -s ${{ matrix.molecule_test }} working-directory: ./ansible_collections/middleware_automation/keycloak diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 071821d..20cbc1e 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -26,7 +26,7 @@ jobs: pages: write steps: - name: Check out code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: ansible_collections/middleware_automation/keycloak fetch-depth: 0 @@ -34,7 +34,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: 3.11 cache: 'pip' - name: Install doc dependencies diff --git a/docs/conf.py b/docs/conf.py index 31502f3..c1b24a9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -43,6 +43,7 @@ extensions = [ 'myst_parser', 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', + 'sphinx_antsibull_ext', 'ansible_basic_sphinx_ext', ] @@ -71,7 +72,7 @@ language = None exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.tmp'] # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = 'ansible' highlight_language = 'YAML+Jinja' diff --git a/docs/requirements.txt b/docs/requirements.txt index c43be53..c8f8e2d 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,6 +2,7 @@ antsibull>=0.17.0 antsibull-docs antsibull-changelog ansible-core>=2.14.1 +ansible-pygments sphinx-rtd-theme git+https://github.com/felixfontein/ansible-basic-sphinx-ext myst-parser From ca2dbe78c235504d2de9571ab0dac0fcce331ecb Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 24 Aug 2023 13:46:50 +0200 Subject: [PATCH 062/376] ci: update workflows --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9a5105d..b9917b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -123,7 +123,7 @@ jobs: - name: Install yamllint, ansible and molecule run: | python -m pip install --upgrade pip - pip install yamllint 'molecule>=4.0.4' 'molecule-plugins[docker]>=23.0.0' ansible-core flake8 ansible-lint voluptuous + pip install 'molecule>=5.0.1' 'molecule-plugins[docker]>=23.0.0' ansible-coreansible-core==${{ matrix.ansible_version }} if [ -f ansible_collections/middleware_automation/keycloak/requirements.txt ]; then pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt fi From 0783000849149d98fa491f66b3e84d2656bfe53d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 24 Aug 2023 13:53:22 +0200 Subject: [PATCH 063/376] ci: update workflows --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9917b6..6534841 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -123,7 +123,7 @@ jobs: - name: Install yamllint, ansible and molecule run: | python -m pip install --upgrade pip - pip install 'molecule>=5.0.1' 'molecule-plugins[docker]>=23.0.0' ansible-coreansible-core==${{ matrix.ansible_version }} + pip install 'molecule>=5.0.1' 'molecule-plugins[docker]>=23.0.0' ansible-core==${{ matrix.ansible_version }} if [ -f ansible_collections/middleware_automation/keycloak/requirements.txt ]; then pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt fi From 52518264770ccbb2564564c1182a5ed742e7a8d6 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 24 Aug 2023 13:57:38 +0200 Subject: [PATCH 064/376] ci: update workflows --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6534841..cb1efcd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -135,7 +135,9 @@ jobs: fi - name: Run molecule test - run: molecule test -s ${{ matrix.molecule_test }} + run: | + molecule --version + molecule test -s ${{ matrix.molecule_test }} working-directory: ./ansible_collections/middleware_automation/keycloak env: PY_COLORS: '1' From 7c05ee5239c044603c0354bdbe235fb594925bd2 Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 25 Aug 2023 11:38:45 +0200 Subject: [PATCH 065/376] Update Keycloak to version 22.0.1 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 9fd6041..3e3d923 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -30,13 +30,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-22.0.0/conf/ + path: /opt/keycloak/keycloak-22.0.1/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-22.0.0/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-22.0.1/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index cd5383f..cda65aa 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.0` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.1` | * Service configuration @@ -71,7 +71,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.0` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.1` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 53a9c76..bab1885 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 22.0.0 +keycloak_quarkus_version: 22.0.1 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From 11621516e36be6bb9aff88e3cd79c60858e0f90d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 25 Aug 2023 11:40:27 +0200 Subject: [PATCH 066/376] update workflows --- .github/workflows/ci.yml | 141 ++----------------------------------- .github/workflows/docs.yml | 57 ++------------- 2 files changed, 12 insertions(+), 186 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb1efcd..a771a4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,138 +8,11 @@ on: schedule: - cron: '0 6 * * *' -env: - COLORTERM: 'yes' - TERM: 'xterm-256color' - PYTEST_ADDOPTS: '--color=yes' - jobs: - linter: - runs-on: ubuntu-latest - strategy: - matrix: - python_version: ["3.11"] - ansible_version: ["2.15"] - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - path: ansible_collections/middleware_automation/keycloak - - - name: Set up Python ${{ matrix.python_version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python_version }} - cache: 'pip' - - - name: Create default collection path - run: | - mkdir -p /home/runner/.ansible/ - ln -s ${{ github.workspace }} /home/runner/.ansible/collections - - - name: Install yamllint, ansible and dependencies - run: | - python -m pip install --upgrade pip - pip install yamllint ansible-core==${{ matrix.ansible_version }} ansible-lint - if [ -f ansible_collections/middleware_automation/keycloak/requirements.txt ]; then - pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt - fi - if [ -f ansible_collections/middleware_automation/keycloak/requirements.yml ]; then - ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/requirements.yml -p /home/runner/.ansible/collections --force-with-deps - fi - - - name: Install ansible-lint custom rules - uses: actions/checkout@v3 - with: - repository: ansible-middleware/ansible-lint-custom-rules - path: ansible-lint-custom-rules/ - - - name: Run linter - run: | - ansible-lint --version - ansible-lint -v - working-directory: ./ansible_collections/middleware_automation/keycloak - - sanity: - runs-on: ubuntu-latest - strategy: - matrix: - python_version: ["3.8", "3.9", "3.11"] - ansible_version: ["2.11", "2.15"] - exclude: - - python_version: "3.8" - ansible_version: "2.15" - - python_version: "3.9" - ansible_version: "2.15" - - python_version: "3.11" - ansible_version: "2.11" - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - path: ansible_collections/middleware_automation/keycloak - - - name: Set up Python ${{ matrix.python_version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python_version }} - cache: 'pip' - - - name: Create default collection path - run: | - mkdir -p /home/runner/.ansible/ - ln -s ${{ github.workspace }} /home/runner/.ansible/collections - - - name: Install ansible-core stable-${{ matrix.ansible_version }} - run: | - pip install https://github.com/ansible/ansible/archive/stable-${{ matrix.ansible_version }}.tar.gz --disable-pip-version-check - - - name: Run sanity tests - run: ansible-test sanity -v --color --docker --python ${{ matrix.python_version }} --exclude docs/conf.py --exclude changelogs/fragments/.gitignore --skip-test symlinks - working-directory: ./ansible_collections/middleware_automation/keycloak - - molecule: - runs-on: ubuntu-latest - strategy: - matrix: - python_version: ["3.11"] - ansible_version: ["2.14", "2.15"] - molecule_test: - - default - - quarkus - - overridexml - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - path: ansible_collections/middleware_automation/keycloak - - - name: Set up Python ${{ matrix.python_version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python_version }} - cache: 'pip' - - - name: Install yamllint, ansible and molecule - run: | - python -m pip install --upgrade pip - pip install 'molecule>=5.0.1' 'molecule-plugins[docker]>=23.0.0' ansible-core==${{ matrix.ansible_version }} - if [ -f ansible_collections/middleware_automation/keycloak/requirements.txt ]; then - pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt - fi - if [ -f ansible_collections/middleware_automation/keycloak/requirements.yml ]; then - ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/requirements.yml -p /home/runner/.ansible/collections --force-with-deps - fi - if [ -f ansible_collections/middleware_automation/keycloak/molecule/requirements.yml ]; then - ansible-galaxy collection install -r ansible_collections/middleware_automation/keycloak/molecule/requirements.yml -p /home/runner/.ansible/collections - fi - - - name: Run molecule test - run: | - molecule --version - molecule test -s ${{ matrix.molecule_test }} - working-directory: ./ansible_collections/middleware_automation/keycloak - env: - PY_COLORS: '1' - ANSIBLE_FORCE_COLOR: '1' - ANSIBLE_VERBOSITY: '1' + ci: + uses: ansible-middleware/github-actions/.github/workflows/ci.yml@main + secrets: inherit + with: + fqcn: 'middleware_automation/keycloak' + molecule_tests: >- + [ "default", "quarkus", "overridexml" ] diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 20cbc1e..c1a95bf 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -8,57 +8,10 @@ on: - "[0-9]+.[0-9]+.[0-9]+" workflow_dispatch: -env: - COLORTERM: 'yes' - TERM: 'xterm-256color' - PYTEST_ADDOPTS: '--color=yes' - jobs: docs: - runs-on: ubuntu-latest - if: github.repository == 'ansible-middleware/keycloak' - permissions: - actions: write - checks: write - contents: write - deployments: write - packages: write - pages: write - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - path: ansible_collections/middleware_automation/keycloak - fetch-depth: 0 - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: 3.11 - cache: 'pip' - - - name: Install doc dependencies - run: | - python -m pip install --upgrade pip - pip install -r ansible_collections/middleware_automation/keycloak/docs/requirements.txt - pip install -r ansible_collections/middleware_automation/keycloak/requirements.txt - sudo apt --fix-missing update - sudo apt install -y sed hub - - - name: Create default collection path - run: | - mkdir -p /home/runner/.ansible/ - ln -s /home/runner/work/keycloak/keycloak /home/runner/.ansible/collections - - - name: Create changelog and documentation - uses: ansible-middleware/collection-docs-action@main - with: - collection_fqcn: middleware_automation.keycloak - collection_repo: ansible-middleware/keycloak - dependencies: false - commit_changelog: false - commit_ghpages: true - changelog_release: false - generate_docs: true - path: ansible_collections/middleware_automation/keycloak - token: ${{ secrets.GITHUB_TOKEN }} + uses: ansible-middleware/github-actions/.github/workflows/docs.yml@main + secrets: inherit + with: + fqcn: 'middleware_automation/keycloak' + collection_fqcn: 'middleware_automation.keycloak' From 6e6bf2ff716d670a2aeba78e5ba75cdb85a7a30d Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Sun, 27 Aug 2023 21:57:25 +0200 Subject: [PATCH 067/376] Fix JRE version in README --- roles/keycloak_quarkus/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index cda65aa..b528944 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -30,7 +30,7 @@ Role Defaults |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` | |`keycloak_quarkus_service_pidfile`| Pid file path for service | `/run/keycloak.pid` | -|`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-11-openjdk-headless` | +|`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | |`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | |`keycloak_quarkus_frontend_url`| Service public URL | `http://localhost:8080/auth` | From 5c8d7d9554c9933f2a994597529e899d8d6f5e5e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 28 Aug 2023 17:45:40 +0200 Subject: [PATCH 068/376] ci: update release workflow --- .github/workflows/release.yml | 87 ++--------------------------------- 1 file changed, 4 insertions(+), 83 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ff64240..5e14f9c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,89 +5,10 @@ on: jobs: release: - runs-on: ubuntu-latest - if: github.repository == 'ansible-middleware/keycloak' - permissions: - actions: write - checks: write - contents: write - deployments: write - packages: write - pages: write - outputs: - tag_version: ${{ steps.get_version.outputs.TAG_VERSION }} - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - fetch-depth: 0 - token: ${{ secrets.TRIGGERING_PAT }} - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: "3.x" - cache: 'pip' - - - name: Get current version - id: get_version - run: echo "::set-output name=TAG_VERSION::$(grep version galaxy.yml | awk -F'"' '{ print $2 }')" - - - name: Check if tag exists - id: check_tag - run: echo "::set-output name=TAG_EXISTS::$(git tag | grep ${{ steps.get_version.outputs.TAG_VERSION }})" - - - name: Fail if tag exists - if: ${{ steps.get_version.outputs.TAG_VERSION == steps.check_tag.outputs.TAG_EXISTS }} - uses: actions/github-script@v3 - with: - script: | - core.setFailed('Release tag already exists') - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install ansible-core antsibull - sudo apt --fix-missing update - sudo apt install -y sed hub - - - name: Build collection - run: | - ansible-galaxy collection build . - - - name: Create changelog and documentation - uses: ansible-middleware/collection-docs-action@main - with: - collection_fqcn: middleware_automation.keycloak - collection_repo: ansible-middleware/keycloak - dependencies: false - commit_changelog: true - commit_ghpages: false - changelog_release: true - generate_docs: false - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Publish collection - env: - ANSIBLE_GALAXY_API_KEY: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} - run: | - ansible-galaxy collection publish *.tar.gz --api-key $ANSIBLE_GALAXY_API_KEY - - - name: Create release tag - run: | - git config user.name github-actions - git config user.email github-actions@github.com - git tag -a ${{ steps.get_version.outputs.TAG_VERSION }} -m "Release v${{ steps.get_version.outputs.TAG_VERSION }}" || true - git push origin --tags - - - name: Publish Release - uses: softprops/action-gh-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ steps.get_version.outputs.TAG_VERSION }} - files: "*.tar.gz" - body_path: gh-release.md + uses: ansible-middleware/github-actions/.github/workflows/release.yml@main + secrets: inherit + with: + collection_fqcn: 'middleware_automation.keycloak' dispatch: needs: release From 6330f08b287f8aca05a2a13514136c6942637bf1 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 28 Aug 2023 15:55:52 +0000 Subject: [PATCH 069/376] Update changelog for release 1.2.8 Signed-off-by: github-actions --- CHANGELOG.rst | 16 ++++++++++++++++ changelogs/changelog.yaml | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 566fc60..694df90 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,22 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.2.8 +====== + +Minor Changes +------------- + +- keycloak_quarkus: set openjdk 17 as default `#103 `_ +- keycloak_quarkus: update to version 22.0.1 `#107 `_ + +Bugfixes +-------- + +- Fix incorrect checks for ``keycloak_jgroups_subnet`` `#98 `_ +- Undefine ``keycloak_db_valid_conn_sql`` default `#91 `_ +- Update bindep.txt package python3-devel to support RHEL9 `#105 `_ + v1.2.7 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index b6e6bd1..272d30d 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -260,3 +260,29 @@ releases: - 92.yaml - 93.yaml release_date: '2023-06-19' + 1.2.8: + changes: + bugfixes: + - 'Fix incorrect checks for ``keycloak_jgroups_subnet`` `#98 `_ + + ' + - 'Undefine ``keycloak_db_valid_conn_sql`` default `#91 `_ + + ' + - 'Update bindep.txt package python3-devel to support RHEL9 `#105 `_ + + ' + minor_changes: + - 'keycloak_quarkus: set openjdk 17 as default `#103 `_ + + ' + - 'keycloak_quarkus: update to version 22.0.1 `#107 `_ + + ' + fragments: + - 103.yaml + - 105.yaml + - 107.yaml + - 91.yaml + - 98.yaml + release_date: '2023-08-28' From df7fab8f41e0b46d4e3b9ec928b66c10364043c1 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 28 Aug 2023 15:56:38 +0000 Subject: [PATCH 070/376] Bump version to 1.2.9 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index a2eeccb..7d0d7de 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.8" +version: "1.2.9" readme: README.md authors: - Romain Pelisse From 40c015d3e170fc06f3ec6da1a8cca3f70609a86a Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Tue, 29 Aug 2023 21:41:38 +0200 Subject: [PATCH 071/376] always create pidfile folder add keycloak_service_runas feature flag fix previous installs permissions --- roles/keycloak/meta/argument_specs.yml | 5 +++++ roles/keycloak/tasks/install.yml | 18 +++++++++--------- roles/keycloak/templates/keycloak.service.j2 | 2 ++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index daba3ba..db73f3f 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -74,6 +74,11 @@ argument_specs: default: "" description: "Path to custom template for standalone.xml configuration" type: "str" + keycloak_service_runas: + # line 20 of keycloak/defaults/main.yml + default: false + description: "Enable execution of service as `keycloak_service_user`" + type: "bool" keycloak_service_user: # line 29 of keycloak/defaults/main.yml default: "keycloak" diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 13f4ef3..a2467d3 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -53,20 +53,14 @@ group: "{{ keycloak_service_group }}" mode: 0750 -- name: Check pidfile folder - ansible.builtin.stat: - path: "{{ keycloak_service_pidfile | dirname }}" - register: keycloak_service_pidfile_stat - name: Create pidfile folder become: yes - become_user: root ansible.builtin.file: dest: "{{ keycloak_service_pidfile | dirname }}" state: directory - owner: "{{ keycloak_service_user }}" - group: "{{ keycloak_service_group }}" - mode: "0750" - when: not keycloak_service_pidfile_stat.stat.exists + owner: "{{ keycloak_service_user if keycloak_service_runas else omit }}" + group: "{{ keycloak_service_group if keycloak_service_runas else omit }}" + mode: 0750 ## check remote archive - name: Set download archive path @@ -209,6 +203,12 @@ become: yes changed_when: false +- name: Ensure permissions are correct on existing deploy + ansible.builtin.command: chown -R "{{ keycloak_service_user }}:{{ keycloak_service_group }}" "{{ keycloak.home }}" + when: keycloak_service_runas + become: yes + changed_when: false + # driver and configuration - name: "Install {{ keycloak_jdbc_engine }} driver" ansible.builtin.include_tasks: jdbc_driver.yml diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index 8a94c62..cc4f324 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -8,8 +8,10 @@ StartLimitBurst={{ keycloak_service_startlimitburst }} [Service] Type=forking +{% if keycloak_service_runas %} User={{ keycloak_service_user }} Group={{ keycloak_service_group }} +{% endif -%} EnvironmentFile=-/etc/sysconfig/keycloak PIDFile={{ keycloak_service_pidfile }} ExecStart={{ keycloak_dest }}/keycloak-service.sh start From 276444ce0ecb721250235881cdf20bba823e761d Mon Sep 17 00:00:00 2001 From: Massimo Schiavon Date: Tue, 29 Aug 2023 22:02:18 +0200 Subject: [PATCH 072/376] Add default for keycloak_service_runas --- roles/keycloak/defaults/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 156af46..9e09804 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -17,6 +17,7 @@ keycloak_config_standalone_xml: "keycloak.xml" keycloak_config_path_to_standalone_xml: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}" keycloak_config_override_template: '' keycloak_config_path_to_properties: "{{ keycloak_jboss_home }}/standalone/configuration/profile.properties" +keycloak_service_runas: false keycloak_service_user: keycloak keycloak_service_group: keycloak keycloak_service_pidfile: "/run/keycloak/keycloak.pid" From 0199e554b53ba811ac1e91def7f1afe300f982c7 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 30 Aug 2023 10:16:41 +0200 Subject: [PATCH 073/376] overridexml test uses runas feature --- molecule/overridexml/converge.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/molecule/overridexml/converge.yml b/molecule/overridexml/converge.yml index 3c451da..e0bed70 100644 --- a/molecule/overridexml/converge.yml +++ b/molecule/overridexml/converge.yml @@ -6,6 +6,7 @@ keycloak_config_override_template: custom.xml.j2 keycloak_http_port: 8081 keycloak_management_http_port: 19990 + keycloak_service_runas: True roles: - role: keycloak tasks: @@ -51,4 +52,4 @@ sso_offline_install: True when: - assets_server is defined - - assets_server | length > 0 \ No newline at end of file + - assets_server | length > 0 From 7bb9647d0d1602dece70d9386cb9a5a6348f9993 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 30 Aug 2023 10:58:37 +0200 Subject: [PATCH 074/376] update systemd unit to use standalone.sh directly --- roles/keycloak/templates/keycloak-sysconfig.j2 | 10 +++++++++- roles/keycloak/templates/keycloak.service.j2 | 5 ++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/roles/keycloak/templates/keycloak-sysconfig.j2 b/roles/keycloak/templates/keycloak-sysconfig.j2 index 68474c3..86a96d6 100644 --- a/roles/keycloak/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak/templates/keycloak-sysconfig.j2 @@ -8,4 +8,12 @@ KEYCLOAK_HTTPS_PORT={{ keycloak_https_port }} KEYCLOAK_MANAGEMENT_HTTP_PORT={{ keycloak_management_http_port }} KEYCLOAK_MANAGEMENT_HTTPS_PORT={{ keycloak_management_https_port }} JBOSS_PIDFILE='{{ keycloak_service_pidfile }}' -LAUNCH_JBOSS_IN_BACKGROUND=1 \ No newline at end of file + +WILDFLY_OPTS=-Djboss.bind.address=${KEYCLOAK_BIND_ADDRESS} \ + -Djboss.http.port=${KEYCLOAK_HTTP_PORT} \ + -Djboss.https.port=${KEYCLOAK_HTTPS_PORT} \ + -Djboss.management.http.port=${KEYCLOAK_MANAGEMENT_HTTP_PORT} \ + -Djboss.management.https.port=${KEYCLOAK_MANAGEMENT_HTTPS_PORT} \ + -Djboss.node.name={{ inventory_hostname }} \ + {% if keycloak_prefer_ipv4 %}-Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses=true {% endif %}\ + {% if keycloak_config_standalone_xml is defined %}--server-config={{ keycloak_config_standalone_xml }}{% endif %} diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index cc4f324..15a6ddf 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -7,15 +7,14 @@ StartLimitBurst={{ keycloak_service_startlimitburst }} [Service] -Type=forking {% if keycloak_service_runas %} User={{ keycloak_service_user }} Group={{ keycloak_service_group }} {% endif -%} EnvironmentFile=-/etc/sysconfig/keycloak PIDFile={{ keycloak_service_pidfile }} -ExecStart={{ keycloak_dest }}/keycloak-service.sh start -ExecStop={{ keycloak_dest }}/keycloak-service.sh stop +ExecStart={{ keycloak.home }}/bin/standalone.sh $WILDFLY_OPTS +WorkingDirectory={{ keycloak.home }} TimeoutStartSec=30 TimeoutStopSec=30 LimitNOFILE=102642 From 6c65fadf310f12ca5feefe32ab4b611d51edaf34 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 30 Aug 2023 11:13:17 +0200 Subject: [PATCH 075/376] Bump version to 1.3.0 --- galaxy.yml | 2 +- molecule/default/molecule.yml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index 7d0d7de..82709bd 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.2.9" +version: "1.3.0" readme: README.md authors: - Romain Pelisse diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index abdc729..c133eee 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -28,7 +28,6 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" - ANSIBLE_VERBOSITY: 3 verifier: name: ansible scenario: From b72460e4641a69ea2612ffa71a85dfca716fdb27 Mon Sep 17 00:00:00 2001 From: Miles Sherman Date: Mon, 18 Sep 2023 14:46:56 +0000 Subject: [PATCH 076/376] quarkus role: do not populate proxy to config if keycloak_quarkus_proxy_mode is undefined or set to 'none' --- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 600e9d1..ab883fc 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -34,8 +34,10 @@ cache-config-file=cache-ispn.xml cache-stack=tcp {% endif %} +{% if keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %} # Proxy proxy={{ keycloak_quarkus_proxy_mode }} +{% endif %} # Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy #spi-sticky-session-encoder-infinispan-should-attach-route=false From d673fcf48a679a3f49ad65c39fff180598b18968 Mon Sep 17 00:00:00 2001 From: Miles Sherman Date: Mon, 18 Sep 2023 17:21:45 +0000 Subject: [PATCH 077/376] update documentation for change to keycloak_quarkus_proxy_mode handling --- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 9081336..bd98cdb 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -49,7 +49,7 @@ keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False keycloak_quarkus_http_relative_path: auth keycloak_quarkus_frontend_url: http://localhost:8080/auth -# proxy address forwarding mode if the server is behind a reverse proxy. [edge, reencrypt, passthrough] +# proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge # disable xa transactions diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 2986c0c..8e7f08a 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -243,7 +243,7 @@ argument_specs: keycloak_quarkus_proxy_mode: default: 'edge' type: "str" - description: "The proxy address forwarding mode if the server is behind a reverse proxy" + description: "The proxy address forwarding mode if the server is behind a reverse proxy. Set to 'none' if not using a proxy" keycloak_quarkus_start_dev: default: False type: "bool" From 942b5fce0f88b2b5417d95a6a0144357b28b6fd8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 19 Sep 2023 12:22:39 +0200 Subject: [PATCH 078/376] add molecule quarkus keycloak in dev-mode test --- molecule/quarkus-devmode/converge.yml | 44 ++++++++++++++++++++++++++ molecule/quarkus-devmode/molecule.yml | 45 +++++++++++++++++++++++++++ molecule/quarkus-devmode/prepare.yml | 12 +++++++ molecule/quarkus-devmode/roles | 1 + molecule/quarkus-devmode/verify.yml | 39 +++++++++++++++++++++++ 5 files changed, 141 insertions(+) create mode 100644 molecule/quarkus-devmode/converge.yml create mode 100644 molecule/quarkus-devmode/molecule.yml create mode 100644 molecule/quarkus-devmode/prepare.yml create mode 120000 molecule/quarkus-devmode/roles create mode 100644 molecule/quarkus-devmode/verify.yml diff --git a/molecule/quarkus-devmode/converge.yml b/molecule/quarkus-devmode/converge.yml new file mode 100644 index 0000000..b484120 --- /dev/null +++ b/molecule/quarkus-devmode/converge.yml @@ -0,0 +1,44 @@ +--- +- name: Converge + hosts: all + vars: + keycloak_quarkus_admin_pass: "remembertochangeme" + keycloak_admin_password: "remembertochangeme" + keycloak_realm: TestRealm + keycloak_quarkus_http_relative_path: '' + keycloak_quarkus_log: file + keycloak_quarkus_frontend_url: 'http://localhost:8080/' + keycloak_quarkus_start_dev: True + keycloak_quarkus_proxy_mode: none + roles: + - role: keycloak_quarkus + - role: keycloak_realm + keycloak_context: '' + keycloak_client_default_roles: + - TestRoleAdmin + - TestRoleUser + keycloak_client_users: + - username: TestUser + password: password + client_roles: + - client: TestClient + role: TestRoleUser + realm: "{{ keycloak_realm }}" + - username: TestAdmin + password: password + client_roles: + - client: TestClient + role: TestRoleUser + realm: "{{ keycloak_realm }}" + - client: TestClient + role: TestRoleAdmin + realm: "{{ keycloak_realm }}" + keycloak_realm: TestRealm + keycloak_clients: + - name: TestClient + roles: "{{ keycloak_client_default_roles }}" + realm: "{{ keycloak_realm }}" + public_client: "{{ keycloak_client_public }}" + web_origins: "{{ keycloak_client_web_origins }}" + users: "{{ keycloak_client_users }}" + client_id: TestClient diff --git a/molecule/quarkus-devmode/molecule.yml b/molecule/quarkus-devmode/molecule.yml new file mode 100644 index 0000000..191234d --- /dev/null +++ b/molecule/quarkus-devmode/molecule.yml @@ -0,0 +1,45 @@ +--- +driver: + name: docker +platforms: + - name: instance + image: registry.access.redhat.com/ubi8/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + port_bindings: + - "8080/tcp" + - "8009/tcp" + published_ports: + - 0.0.0.0:8080:8080/tcp +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + ssh_connection: + pipelining: false + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + env: + ANSIBLE_FORCE_COLOR: "true" +verifier: + name: ansible +scenario: + test_sequence: + - cleanup + - destroy + - create + - prepare + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/quarkus-devmode/prepare.yml b/molecule/quarkus-devmode/prepare.yml new file mode 100644 index 0000000..09cbda3 --- /dev/null +++ b/molecule/quarkus-devmode/prepare.yml @@ -0,0 +1,12 @@ +--- +- name: Prepare + hosts: all + tasks: + - name: Install sudo + ansible.builtin.yum: + name: sudo + state: present + + - name: "Display hera_home if defined." + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" diff --git a/molecule/quarkus-devmode/roles b/molecule/quarkus-devmode/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/quarkus-devmode/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/molecule/quarkus-devmode/verify.yml b/molecule/quarkus-devmode/verify.yml new file mode 100644 index 0000000..ebb6047 --- /dev/null +++ b/molecule/quarkus-devmode/verify.yml @@ -0,0 +1,39 @@ +--- +- name: Verify + hosts: all + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + + - name: Check if keycloak service started + ansible.builtin.assert: + that: + - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" + + - name: Set internal envvar + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - name: Verify openid config + block: + - name: Fetch openID config # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + curl http://localhost:8080/realms/master/.well-known/openid-configuration -k | jq . + args: + executable: /bin/bash + delegate_to: localhost + register: openid_config + changed_when: False + - name: Verify endpoint URLs + ansible.builtin.assert: + that: + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'http://localhost:8080/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'http://localhost:8080/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'http://localhost:8080/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'http://localhost:8080/realms/master/protocol/openid-connect/token' + delegate_to: localhost + when: + - hera_home is defined + - hera_home | length == 0 From 0f17e0973173bd5e2a4ce721b5b75a7367b80425 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 19 Sep 2023 12:25:38 +0200 Subject: [PATCH 079/376] add new test to CI --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a771a4d..50e1fc4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml" ] + [ "default", "quarkus", "overridexml", "quarkus-devmode" ] From 9a46b455f6abcc90f361f6cf45ba0b380a5dbd82 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Tue, 19 Sep 2023 13:53:32 +0200 Subject: [PATCH 080/376] Fix admin login redirect when running locally --- roles/keycloak_quarkus/defaults/main.yml | 1 + roles/keycloak_quarkus/templates/keycloak.conf.j2 | 1 + 2 files changed, 2 insertions(+) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index bd98cdb..bb7eb79 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -28,6 +28,7 @@ keycloak_quarkus_master_realm: master ### Configuration settings keycloak_quarkus_bind_address: 0.0.0.0 keycloak_quarkus_host: localhost +keycloak_quarkus_port: 8080 keycloak_quarkus_http_enabled: True keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index ab883fc..7285c48 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -25,6 +25,7 @@ https-certificate-key-file={{ keycloak_quarkus_key_file }} # Hostname for the Keycloak server. hostname={{ keycloak_quarkus_host }} +hostname-port={{ keycloak_quarkus_port }} hostname-path={{ keycloak_quarkus_http_relative_path }} # Cluster From 9c361c96280b67f76938212b796a019e5002ed15 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Tue, 19 Sep 2023 13:56:51 +0200 Subject: [PATCH 081/376] add in README --- roles/keycloak_quarkus/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index b528944..03bd4e2 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -22,9 +22,10 @@ Role Defaults |`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` | |`keycloak_quarkus_admin_user`| Administration console user account | `admin` | |`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | -|`keycloak_quarkus_host`| hostname | `localhost` | -|`keycloak_quarkus_http_port`| HTTP port | `8080` | -|`keycloak_quarkus_https_port`| TLS HTTP port | `8443` | +|`keycloak_quarkus_host`| Hostname from where application is reachable by clients | `localhost` | +|`keycloak_quarkus_port`| Port from where application is reachable by clients | `8080` | +|`keycloak_quarkus_http_port`| HTTP listening port | `8080` | +|`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` | |`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7600` | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | From 38ff5196249c84646ef08760e8d2374c91de24f1 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Tue, 19 Sep 2023 14:00:15 +0200 Subject: [PATCH 082/376] update arguments --- roles/keycloak_quarkus/meta/argument_specs.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 8e7f08a..8967633 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -90,10 +90,13 @@ argument_specs: description: "Address for binding service ports" type: "str" keycloak_quarkus_host: - # line 28 of defaults/main.yml default: "localhost" - description: "hostname" + description: "Hostname from where application is reachable by clients" type: "str" + keycloak_quarkus_port: + default: 8080 + description: "Port from where application is reachable by clients" + type: "int" keycloak_quarkus_http_enabled: default: true description: "Enable listener on HTTP port" From f0f90b8930cd274d06842689fa3b7dd0b50d52a6 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Tue, 19 Sep 2023 17:05:00 +0200 Subject: [PATCH 083/376] apply review suggestions --- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 03bd4e2..578b6fe 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -22,8 +22,8 @@ Role Defaults |`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` | |`keycloak_quarkus_admin_user`| Administration console user account | `admin` | |`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | -|`keycloak_quarkus_host`| Hostname from where application is reachable by clients | `localhost` | -|`keycloak_quarkus_port`| Port from where application is reachable by clients | `8080` | +|`keycloak_quarkus_host`| Hostname for the Keycloak server | `localhost` | +|`keycloak_quarkus_port`| The port used by the proxy when exposing the hostname | `-1` | |`keycloak_quarkus_http_port`| HTTP listening port | `8080` | |`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index bb7eb79..075ba93 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -28,7 +28,7 @@ keycloak_quarkus_master_realm: master ### Configuration settings keycloak_quarkus_bind_address: 0.0.0.0 keycloak_quarkus_host: localhost -keycloak_quarkus_port: 8080 +keycloak_quarkus_port: -1 keycloak_quarkus_http_enabled: True keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 8967633..59f3e50 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -91,11 +91,11 @@ argument_specs: type: "str" keycloak_quarkus_host: default: "localhost" - description: "Hostname from where application is reachable by clients" + description: "Hostname for the Keycloak server" type: "str" keycloak_quarkus_port: - default: 8080 - description: "Port from where application is reachable by clients" + default: -1 + description: "The port used by the proxy when exposing the hostname" type: "int" keycloak_quarkus_http_enabled: default: true From 194101f01041b719485cc3035d3f48ffffc01449 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Tue, 19 Sep 2023 17:14:17 +0200 Subject: [PATCH 084/376] add new playbook example for localhost quarkus --- playbooks/keycloak_quarkus.yml | 5 +++-- playbooks/keycloak_quarkus_dev.yml | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 playbooks/keycloak_quarkus_dev.yml diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index 9e1d3f9..7c657b7 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -1,9 +1,10 @@ --- -- name: Playbook for Keycloak X Hosts +- name: Playbook for Keycloak X Hosts with HTTPS enabled hosts: all vars: keycloak_admin_password: "remembertochangeme" - keycloak_quarkus_host: localhost:8443 + keycloak_quarkus_host: localhost + keycloak_quarkus_port: 8443 keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file keycloak_quarkus_https_enabled: True diff --git a/playbooks/keycloak_quarkus_dev.yml b/playbooks/keycloak_quarkus_dev.yml new file mode 100644 index 0000000..634296d --- /dev/null +++ b/playbooks/keycloak_quarkus_dev.yml @@ -0,0 +1,13 @@ +--- +- name: Playbook for Keycloak X Hosts in develop mode + hosts: all + vars: + keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_host: localhost + keycloak_quarkus_port: 8080 + keycloak_quarkus_http_relative_path: '' + keycloak_quarkus_log: file + keycloak_quarkus_start_dev: true + keycloak_quarkus_proxy_mode: none + roles: + - middleware_automation.keycloak.keycloak_quarkus From 3bb32ed075a72125875ef8f77155842d7082eb0e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 21 Sep 2023 12:33:29 +0200 Subject: [PATCH 085/376] ci: update release wf --- .github/workflows/release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5e14f9c..7ea4aab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,9 +6,10 @@ on: jobs: release: uses: ansible-middleware/github-actions/.github/workflows/release.yml@main - secrets: inherit with: collection_fqcn: 'middleware_automation.keycloak' + secrets: + galaxy_token: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} dispatch: needs: release From cb25c28bb83081c81a00adb3c46c61e55d4375bb Mon Sep 17 00:00:00 2001 From: footur <3769085+Footur@users.noreply.github.com> Date: Fri, 22 Sep 2023 15:42:06 +0200 Subject: [PATCH 086/376] Update Keycloak to version 22.0.3 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 3e3d923..c6ccb76 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -30,13 +30,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-22.0.1/conf/ + path: /opt/keycloak/keycloak-22.0.3/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-22.0.1/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-22.0.3/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 578b6fe..2e389ec 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.3` | * Service configuration @@ -72,7 +72,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.3` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 075ba93..d544605 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 22.0.1 +keycloak_quarkus_version: 22.0.3 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From f3104285bc739494fa9c5c997b0748f2ec49ece5 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Fri, 22 Sep 2023 16:30:16 +0200 Subject: [PATCH 087/376] Enforce service restart when needed before service checking --- roles/keycloak_quarkus/tasks/main.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 1c6c21b..2564345 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -52,6 +52,9 @@ mode: 0775 become: yes +- name: Flush pending handlers + meta: flush_handlers + - name: "Start and wait for keycloak service" ansible.builtin.include_tasks: start.yml From e3ce4bd574e42d6e188e562820142dd884ff0fd5 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo <71768+gionn@users.noreply.github.com> Date: Sat, 23 Sep 2023 18:38:49 +0200 Subject: [PATCH 088/376] fixup linter --- roles/keycloak_quarkus/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 2564345..a86a4f5 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -53,7 +53,7 @@ become: yes - name: Flush pending handlers - meta: flush_handlers + ansible.builtin.meta: flush_handlers - name: "Start and wait for keycloak service" ansible.builtin.include_tasks: start.yml From dded412bd03ffe7a05e5bbe802710db4f33e37f9 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Mon, 25 Sep 2023 10:56:54 +0000 Subject: [PATCH 089/376] Update changelog for release 1.3.0 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 20 ++++++++++++++++++++ changelogs/changelog.yaml | 29 +++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 694df90..8bcfa45 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,26 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v1.3.0 +====== + +Major Changes +------------- + +- Run service as ``keycloak_service_user`` `#106 `_ + +Minor Changes +------------- + +- keycloak_quarkus: Update Keycloak to version 22.0.3 `#112 `_ +- keycloak_quarkus: fix admin console redirect when running locally `#111 `_ +- keycloak_quarkus: skip proxy config if ``keycloak_quarkus_proxy_mode`` is ``none`` `#109 `_ + +Bugfixes +-------- + +- keycloak_quarkus: fix validation failure upon port configuration change `#113 `_ + v1.2.8 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 272d30d..c3b1994 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -286,3 +286,32 @@ releases: - 91.yaml - 98.yaml release_date: '2023-08-28' + 1.3.0: + changes: + bugfixes: + - 'keycloak_quarkus: fix validation failure upon port configuration change `#113 + `_ + + ' + major_changes: + - 'Run service as ``keycloak_service_user`` `#106 `_ + + ' + minor_changes: + - 'keycloak_quarkus: Update Keycloak to version 22.0.3 `#112 `_ + + ' + - 'keycloak_quarkus: fix admin console redirect when running locally `#111 `_ + + ' + - 'keycloak_quarkus: skip proxy config if ``keycloak_quarkus_proxy_mode`` is + ``none`` `#109 `_ + + ' + fragments: + - 106.yaml + - 109.yaml + - 111.yaml + - 112.yaml + - 113.yaml + release_date: '2023-09-25' From 00e6cb6b0e293afc84dcb2720d50373660a592f3 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Mon, 25 Sep 2023 10:57:25 +0000 Subject: [PATCH 090/376] Bump version to 1.3.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 82709bd..5bafaec 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.3.0" +version: "1.3.1" readme: README.md authors: - Romain Pelisse From 0f7bbc7ef9b23364c9b6c18e1d209402bafc0bb5 Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Fri, 13 Oct 2023 16:24:46 +0200 Subject: [PATCH 091/376] Update Keycloak to version 22.0.4 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index c6ccb76..589814a 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -30,13 +30,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-22.0.3/conf/ + path: /opt/keycloak/keycloak-22.0.4/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-22.0.3/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-22.0.4/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 2e389ec..f6e24cc 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.3` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.4` | * Service configuration @@ -72,7 +72,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.3` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.4` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index d544605..0ae35c1 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 22.0.3 +keycloak_quarkus_version: 22.0.4 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From e842462a2260fe81828bfcff9ecf8ba282f7cb46 Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Fri, 13 Oct 2023 16:17:35 +0200 Subject: [PATCH 092/376] Enable config of a key store and trust store --- molecule/quarkus/converge.yml | 2 +- playbooks/keycloak_quarkus.yml | 2 +- roles/keycloak_quarkus/README.md | 9 +++++- roles/keycloak_quarkus/defaults/main.yml | 12 +++++-- .../keycloak_quarkus/meta/argument_specs.yml | 32 ++++++++++++++++--- .../templates/keycloak.conf.j2 | 10 +++++- 6 files changed, 57 insertions(+), 10 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 22f9ff4..6f07938 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -8,7 +8,7 @@ keycloak_quarkus_host: instance keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file - keycloak_quarkus_https_enabled: True + keycloak_quarkus_https_key_file_enabled: True keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/key.pem" keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/cert.pem" roles: diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index 7c657b7..5d34c87 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -7,7 +7,7 @@ keycloak_quarkus_port: 8443 keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file - keycloak_quarkus_https_enabled: True + keycloak_quarkus_https_key_file_enabled: True keycloak_quarkus_key_file: conf/key.pem keycloak_quarkus_cert_file: conf/cert.pem roles: diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 2e389ec..8deeba4 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -37,9 +37,16 @@ Role Defaults |`keycloak_quarkus_frontend_url`| Service public URL | `http://localhost:8080/auth` | |`keycloak_quarkus_http_relative_path` | Service context path | `auth` | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | -|`keycloak_quarkus_https_enabled`| Enable listener on HTTPS port | `False` | +|`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` | |`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `{{ keycloak.home }}/conf/server.key.pem` | |`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `{{ keycloak.home }}/conf/server.crt.pem` | +|`keycloak_quarkus_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` | +|`keycloak_quarkus_key_store_file`| The file pat to the key store | `{{ keycloak.home }}/conf/key_store.p12` | +|`keycloak_quarkus_key_store_password`| Password for the key store | `""` | +|`keycloak_quarkus_https_trust_store_enabled`| Enalbe confiugration of a trust store | `False` | +|`keycloak_quarkus_trust_store_file`| The file pat to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` | +|`keycloak_quarkus_trust_store_password`| Password for the trust store | `""` | + * Database configuration diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index d544605..3e94e37 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -2,7 +2,7 @@ ### Configuration specific to keycloak keycloak_quarkus_version: 22.0.3 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" -keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" +keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" # whether to install from local archive @@ -37,9 +37,17 @@ keycloak_quarkus_jgroups_port: 7600 keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m" ### TLS/HTTPS configuration -keycloak_quarkus_https_enabled: False +keycloak_quarkus_https_key_file_enabled: False keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/server.key.pem" keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/server.crt.pem" +#### key store configuration +keycloak_quarkus_https_key_store_enabled: False +keycloak_quarkus_key_store_file: "{{ keycloak.home }}/conf/key_store.p12" +keycloak_quarkus_key_store_password: '' +##### trust store configuration +keycloak_quarkus_https_trust_store_enabled: False +keycloak_quarkus_trust_store_file: "{{ keycloak.home }}/conf/trust_store.p12" +keycloak_quarkus_trust_store_password: '' ### Enable configuration for database backend, clustering and remote caches on infinispan keycloak_quarkus_ha_enabled: False diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 59f3e50..0d44d4a 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -100,16 +100,16 @@ argument_specs: keycloak_quarkus_http_enabled: default: true description: "Enable listener on HTTP port" - type: "bool" + type: "bool" keycloak_quarkus_http_port: # line 29 of defaults/main.yml default: 8080 description: "HTTP port" type: "int" - keycloak_quarkus_https_enabled: + keycloak_quarkus_https_key_file_enabled: default: false - description: "Enable listener on HTTPS port" - type: "bool" + description: "Enable configuration of HTTPS via files in PEM format" + type: "bool" keycloak_quarkus_key_file: default: "{{ keycloak.home }}/conf/server.key.pem" description: "The file path to a private key in PEM format" @@ -118,6 +118,30 @@ argument_specs: default: "{{ keycloak.home }}/conf/server.crt.pem" description: "The file path to a server certificate or certificate chain in PEM format" type: "str" + keycloak_quarkus_https_key_store_enabled: + default: false + description: "Enable configuration of HTTPS via a key store" + type: "bool" + keycloak_quarkus_key_store_file: + default: "{{ keycloak.home }}/conf/key_store.p12" + description: "The file path to the key store" + type: "str" + keycloak_quarkus_key_store_password: + default: "" + description: "Password for the key store" + type: "str" + keycloak_quarkus_https_trust_store_enabled: + default: false + description: "Enalbe confiugration of a trust store" + type: "bool" + keycloak_quarkus_trust_store_file: + default: "{{ keycloak.home }}/conf/trust_store.p12" + description: "The file pat to the trust store" + type: "str" + keycloak_quarkus_trust_store_password: + default: "" + description: "Password for the trust store" + type: "str" keycloak_quarkus_https_port: # line 30 of defaults/main.yml default: 8443 diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 7285c48..b31f63d 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -18,10 +18,18 @@ http-port={{ keycloak_quarkus_http_port }} # HTTPS https-port={{ keycloak_quarkus_https_port }} -{% if keycloak_quarkus_https_enabled %} +{% if keycloak_quarkus_https_key_file_enabled %} https-certificate-file={{ keycloak_quarkus_cert_file}} https-certificate-key-file={{ keycloak_quarkus_key_file }} {% endif %} +{% if keycloak_quarkus_https_key_store_enabled %} +https-key-store-file={{ keycloak_quarkus_key_store_file }} +https-key-store-password={{ keycloak_quarkus_key_store_password }} +{% endif %} +{% if keycloak_quarkus_https_trust_store_enabled %} +https-trust-store-file={{ keycloak_quarkus_trust_store_file }} +https-trust-store-password={{ keycloak_quarkus_trust_store_password }} +{% endif %} # Hostname for the Keycloak server. hostname={{ keycloak_quarkus_host }} From 307eee771f74dbcbc8188f83e704925438c603a4 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Mon, 16 Oct 2023 12:37:16 +0200 Subject: [PATCH 093/376] Do not require hosts edit for running quarkus molecule suite --- molecule/quarkus/prepare.yml | 15 --------------- molecule/quarkus/verify.yml | 8 ++++---- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index c6ccb76..b83211d 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -7,26 +7,11 @@ name: sudo state: present - - name: "Display hera_home if defined." - ansible.builtin.set_fact: - hera_home: "{{ lookup('env', 'HERA_HOME') }}" - - name: Create certificate request ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' delegate_to: localhost changed_when: False - - name: Set /etc/hosts - ansible.builtin.lineinfile: - dest: /etc/hosts - line: "127.0.0.1 instance" - state: present - delegate_to: localhost - become: yes - when: - - hera_home is defined - - hera_home | length == 0 - - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 553c4d6..e956ca6 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -16,11 +16,14 @@ hera_home: "{{ lookup('env', 'HERA_HOME') }}" - name: Verify openid config + when: + - hera_home is defined + - hera_home | length == 0 block: - name: Fetch openID config # noqa blocked_modules command-instead-of-module ansible.builtin.shell: | set -o pipefail - curl https://instance:8443/realms/master/.well-known/openid-configuration -k | jq . + curl -H 'Host: instance' https://localhost:8443/realms/master/.well-known/openid-configuration -k | jq . args: executable: /bin/bash delegate_to: localhost @@ -34,6 +37,3 @@ - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/auth' - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/token' delegate_to: localhost - when: - - hera_home is defined - - hera_home | length == 0 From bf1cb3695e8c48636da2a4af977d40a0db2d5380 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 16 Oct 2023 15:27:24 +0200 Subject: [PATCH 094/376] Update minimum ansible-core version > 2.14 --- README.md | 2 +- galaxy.yml | 2 +- meta/runtime.yml | 2 +- roles/keycloak/meta/main.yml | 4 ++-- roles/keycloak_quarkus/meta/main.yml | 4 ++-- roles/keycloak_realm/meta/main.yml | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9ae661e..d93231f 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Re ## Ansible version compatibility -This collection has been tested against following Ansible versions: **>=2.9.10**. +This collection has been tested against following Ansible versions: **>=2.14.0**. Plugins and modules within a collection may be tested with only specific Ansible versions. A collection may contain metadata that identifies these versions. diff --git a/galaxy.yml b/galaxy.yml index 5bafaec..ef8da0d 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "1.3.1" +version: "2.0.0" readme: README.md authors: - Romain Pelisse diff --git a/meta/runtime.yml b/meta/runtime.yml index 9baaad6..47dc0fb 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1,2 +1,2 @@ --- -requires_ansible: ">=2.9.10" \ No newline at end of file +requires_ansible: ">=2.14.0" \ No newline at end of file diff --git a/roles/keycloak/meta/main.yml b/roles/keycloak/meta/main.yml index 5816039..5a121ba 100644 --- a/roles/keycloak/meta/main.yml +++ b/roles/keycloak/meta/main.yml @@ -12,12 +12,12 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.9" + min_ansible_version: "2.14" platforms: - name: EL versions: - - 8 + - "8" galaxy_tags: - keycloak diff --git a/roles/keycloak_quarkus/meta/main.yml b/roles/keycloak_quarkus/meta/main.yml index 911a545..2a6acf8 100644 --- a/roles/keycloak_quarkus/meta/main.yml +++ b/roles/keycloak_quarkus/meta/main.yml @@ -8,12 +8,12 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.9" + min_ansible_version: "2.14" platforms: - name: EL versions: - - 8 + - "8" galaxy_tags: - keycloak diff --git a/roles/keycloak_realm/meta/main.yml b/roles/keycloak_realm/meta/main.yml index 5dd7a21..8dfefcd 100644 --- a/roles/keycloak_realm/meta/main.yml +++ b/roles/keycloak_realm/meta/main.yml @@ -8,12 +8,12 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.9" + min_ansible_version: "2.14" platforms: - name: EL versions: - - 8 + - "8" galaxy_tags: - keycloak From d945c511729371eb5343887492ca1a636966ae59 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo <71768+gionn@users.noreply.github.com> Date: Mon, 16 Oct 2023 15:52:04 +0200 Subject: [PATCH 095/376] apply review suggestions --- molecule/quarkus/prepare.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index b83211d..13dfff3 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -7,6 +7,10 @@ name: sudo state: present + - name: "Display hera_home if defined." + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + - name: Create certificate request ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' delegate_to: localhost From 41c13066020450d2560a3935fee1a2c901353294 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 25 Oct 2023 18:20:03 +0200 Subject: [PATCH 096/376] linter --- plugins/modules/keycloak_user_federation.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/modules/keycloak_user_federation.py b/plugins/modules/keycloak_user_federation.py index 96f04d7..bc84d8d 100644 --- a/plugins/modules/keycloak_user_federation.py +++ b/plugins/modules/keycloak_user_federation.py @@ -568,7 +568,6 @@ EXAMPLES = ''' realm: my-realm name: my-federation state: absent - ''' RETURN = ''' From e5f0a3efe10d3ac930b0eeb3981e7f3d1bf631ba Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 25 Oct 2023 16:40:25 +0200 Subject: [PATCH 097/376] molecule test for keycloakx with proxy --- .github/workflows/ci.yml | 2 +- molecule/https_revproxy/converge.yml | 16 ++++++++ molecule/https_revproxy/molecule.yml | 59 ++++++++++++++++++++++++++++ molecule/https_revproxy/prepare.yml | 49 +++++++++++++++++++++++ molecule/https_revproxy/roles | 1 + molecule/https_revproxy/verify.yml | 39 ++++++++++++++++++ molecule/requirements.yml | 2 +- 7 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 molecule/https_revproxy/converge.yml create mode 100644 molecule/https_revproxy/molecule.yml create mode 100644 molecule/https_revproxy/prepare.yml create mode 120000 molecule/https_revproxy/roles create mode 100644 molecule/https_revproxy/verify.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50e1fc4..6e5a542 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml", "quarkus-devmode" ] + [ "default", "quarkus", "overridexml", "quarkus-devmode", "https_revproxy" ] diff --git a/molecule/https_revproxy/converge.yml b/molecule/https_revproxy/converge.yml new file mode 100644 index 0000000..b1eb7bc --- /dev/null +++ b/molecule/https_revproxy/converge.yml @@ -0,0 +1,16 @@ +--- +- name: Converge + hosts: all + vars: + keycloak_quarkus_admin_pass: "remembertochangeme" + keycloak_admin_password: "remembertochangeme" + keycloak_realm: TestRealm + keycloak_quarkus_host: instance + keycloak_quarkus_log: file + keycloak_quarkus_http_enabled: True + keycloak_quarkus_http_port: 8080 + keycloak_quarkus_proxy_mode: edge + keycloak_quarkus_http_relative_path: / + keycloak_quarkus_frontend_url: https://proxy/ + roles: + - role: keycloak_quarkus diff --git a/molecule/https_revproxy/molecule.yml b/molecule/https_revproxy/molecule.yml new file mode 100644 index 0000000..efdebf4 --- /dev/null +++ b/molecule/https_revproxy/molecule.yml @@ -0,0 +1,59 @@ +--- +driver: + name: docker +platforms: + - name: instance + image: registry.access.redhat.com/ubi8/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + networks: + - name: keycloak + port_bindings: + - "8080/tcp" + published_ports: + - 0.0.0.0:8080:8080/tcp + - name: proxy + image: registry.access.redhat.com/ubi8/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + networks: + - name: keycloak + port_bindings: + - "443/tcp" + published_ports: + - 0.0.0.0:443:443/tcp +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + ssh_connection: + pipelining: false + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + env: + ANSIBLE_FORCE_COLOR: "true" + REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID: "${REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID}" + REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET: "${REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET}" +verifier: + name: ansible +scenario: + test_sequence: + - cleanup + - destroy + - create + - prepare + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/https_revproxy/prepare.yml b/molecule/https_revproxy/prepare.yml new file mode 100644 index 0000000..5cdb135 --- /dev/null +++ b/molecule/https_revproxy/prepare.yml @@ -0,0 +1,49 @@ +--- +- name: Prepare + hosts: all + tasks: + - name: Install sudo + ansible.builtin.yum: + name: sudo + state: present + + - name: "Display hera_home if defined." + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + +- name: Prepare proxy + hosts: proxy + vars: + jbcs_mod_cluster_enable: True + jbcs_configure_firewalld: False + jbcs_offline_install: False + jbcs_bind_address: '*' + jbcs_proxy_pass: + - path: / + url: http://instance:8080/ + reverse_path: / + reverse_url: http://instance:8080/ + external_domain_name: proxy + rhn_username: "{{ lookup('env', 'REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID') }}" + rhn_password: "{{ lookup('env', 'REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET') }}" + roles: + - middleware_automation.jbcs.jbcs + pre_tasks: + - name: Create certificate request + ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=proxy' + delegate_to: localhost + changed_when: False + + - name: Copy certificates + ansible.builtin.copy: + src: "{{ item.name }}" + dest: "{{ item.dest }}" + mode: 0444 + become: True + loop: + - { name: 'cert.pem', dest: '/etc/pki/tls/certs/proxy.crt' } + - { name: 'key.pem', dest: '/etc/pki/tls/private/proxy.key' } + + - name: update_ca_trust + command: update-ca-trust + become: True diff --git a/molecule/https_revproxy/roles b/molecule/https_revproxy/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/https_revproxy/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/molecule/https_revproxy/verify.yml b/molecule/https_revproxy/verify.yml new file mode 100644 index 0000000..9d355a6 --- /dev/null +++ b/molecule/https_revproxy/verify.yml @@ -0,0 +1,39 @@ +--- +- name: Verify + hosts: all + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + + - name: Check if keycloak service started + ansible.builtin.assert: + that: + - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" + + - name: Set internal envvar + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - name: Verify openid config + block: + - name: Fetch openID config # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + curl https://localhost:443/realms/master/.well-known/openid-configuration -k | jq . + args: + executable: /bin/bash + register: openid_config + changed_when: False + delegate_to: localhost + - name: Verify endpoint URLs + ansible.builtin.assert: + that: + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://proxy/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'https://proxy/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/token' + delegate_to: localhost + when: + - hera_home is defined + - hera_home | length == 0 diff --git a/molecule/requirements.yml b/molecule/requirements.yml index 2e0ae56..5e39b59 100644 --- a/molecule/requirements.yml +++ b/molecule/requirements.yml @@ -1,8 +1,8 @@ --- collections: - name: middleware_automation.common + - name: middleware_automation.jbcs - name: community.general - name: ansible.posix - name: community.docker version: ">=1.9.1" - From 697023620128485980f5d942fa28a39d7680a983 Mon Sep 17 00:00:00 2001 From: Antonio Costa Date: Wed, 25 Oct 2023 16:03:29 +0200 Subject: [PATCH 098/376] feat: add a destination variable for the log link docs: argument specs for the keycloak_quarkus_log_target docs: added parameter to the roles README fix: role variable is keycloak_log_target and not keycloak_quarkus_log_target --- molecule/default/converge.yml | 1 + molecule/default/verify.yml | 28 +++++++++++++++ molecule/quarkus/converge.yml | 1 + molecule/quarkus/verify.yml | 34 +++++++++++++++++++ roles/keycloak/README.md | 2 +- roles/keycloak/defaults/main.yml | 3 ++ roles/keycloak/meta/argument_specs.yml | 4 +++ roles/keycloak/tasks/main.yml | 2 +- roles/keycloak_quarkus/README.md | 1 + roles/keycloak_quarkus/defaults/main.yml | 1 + .../keycloak_quarkus/meta/argument_specs.yml | 4 +++ roles/keycloak_quarkus/tasks/main.yml | 2 +- 12 files changed, 80 insertions(+), 3 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index d3742e7..afd6ea2 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -10,6 +10,7 @@ port: 16667 - host: myhost2 port: 16668 + keycloak_log_target: /tmp/keycloak roles: - role: keycloak tasks: diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 92a245e..36f49b1 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -55,3 +55,31 @@ ansible.builtin.assert: that: - (keycloak_query_clients.json | selectattr('clientId','equalto','TestClient') | first)["attributes"]["post.logout.redirect.uris"] == '/public/logout' + - name: Check log folder + ansible.builtin.stat: + path: "/tmp/keycloak" + register: keycloak_log_folder + - name: Check that keycloak log folder exists and is a link + ansible.builtin.assert: + that: + - keycloak_log_folder.stat.exists + - not keycloak_log_folder.stat.isdir + - keycloak_log_folder.stat.islnk + - name: Check log file + ansible.builtin.stat: + path: "/tmp/keycloak/server.log" + register: keycloak_log_file + - name: Check if keycloak file exists + ansible.builtin.assert: + that: + - keycloak_log_file.stat.exists + - not keycloak_log_file.stat.isdir + - name: Check default log folder + ansible.builtin.stat: + path: "/var/log/keycloak" + register: keycloak_default_log_folder + failed_when: false + - name: Check that default keycloak log folder doesn't exist + ansible.builtin.assert: + that: + - not keycloak_default_log_folder.stat.exists diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 22f9ff4..cb35230 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -11,6 +11,7 @@ keycloak_quarkus_https_enabled: True keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/key.pem" keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/cert.pem" + keycloak_quarkus_log_target: /tmp/keycloak roles: - role: keycloak_quarkus - role: keycloak_realm diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index e956ca6..2d75c32 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -37,3 +37,37 @@ - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/auth' - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/token' delegate_to: localhost + + - name: Check log folder + ansible.builtin.stat: + path: "/tmp/keycloak" + register: keycloak_log_folder + + - name: Check that keycloak log folder exists and is a link + ansible.builtin.assert: + that: + - keycloak_log_folder.stat.exists + - not keycloak_log_folder.stat.isdir + - keycloak_log_folder.stat.islnk + + - name: Check log file + ansible.builtin.stat: + path: "/tmp/keycloak/keycloak.log" + register: keycloak_log_file + + - name: Check if keycloak file exists + ansible.builtin.assert: + that: + - keycloak_log_file.stat.exists + - not keycloak_log_file.stat.isdir + + - name: Check default log folder + ansible.builtin.stat: + path: "/var/log/keycloak" + register: keycloak_default_log_folder + failed_when: false + + - name: Check that default keycloak log folder doesn't exist + ansible.builtin.assert: + that: + - not keycloak_default_log_folder.stat.exists diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index aae309b..ed10963 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -117,7 +117,7 @@ Role Defaults |`keycloak_db_background_validation_millis`| How frequenly the connection pool is validated in the background | `10000` if background validation enabled | |`keycloak_db_background_validate_on_match` | Enable validate on match for database connections | `False` | |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | - +|`keycloak_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | Role Variables diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 9e09804..124250e 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -114,3 +114,6 @@ keycloak_default_jdbc: version: 12.2.0 # role specific vars keycloak_no_log: True + +### logging configuration +keycloak_log_target: /var/log/keycloak diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index db73f3f..5b64fe9 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -356,6 +356,10 @@ argument_specs: required: False description: "Override the subnet match for jgroups cluster formation; if not defined, it will be inferred from local machine route configuration" type: "str" + keycloak_log_target: + default: '/var/log/keycloak' + type: "str" + description: "Set the destination of the keycloak log folder link" downstream: options: sso_version: diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index 32aca04..7fe0222 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -34,7 +34,7 @@ ansible.builtin.file: state: link src: "{{ keycloak_jboss_home }}/standalone/log" - dest: /var/log/keycloak + dest: "{{ keycloak_log_target }}" become: yes - name: Set admin credentials and restart if not already created diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index f6e24cc..0ea2648 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -97,6 +97,7 @@ Role Defaults |`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` | |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | |`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | +|`keycloak_quarkus_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 0ae35c1..7995d05 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -90,3 +90,4 @@ keycloak_quarkus_log: file keycloak_quarkus_log_level: info keycloak_quarkus_log_file: data/log/keycloak.log keycloak_quarkus_log_format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' +keycloak_quarkus_log_target: /var/log/keycloak diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 59f3e50..32e550b 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -243,6 +243,10 @@ argument_specs: default: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' type: "str" description: "Set a format specific to file log entries" + keycloak_quarkus_log_target: + default: '/var/log/keycloak' + type: "str" + description: "Set the destination of the keycloak log folder link" keycloak_quarkus_proxy_mode: default: 'edge' type: "str" diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index a86a4f5..43cbb38 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -67,6 +67,6 @@ ansible.builtin.file: state: link src: "{{ keycloak.log.file | dirname }}" - dest: /var/log/keycloak + dest: "{{ keycloak_quarkus_log_target }}" force: yes become: yes From 6f26fa3da42c0d92ebc5162be77fd32067a83df7 Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:32:15 +0200 Subject: [PATCH 099/376] Update Keycloak to version 22.0.5 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index f9fe2b7..f90564c 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -19,13 +19,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-22.0.4/conf/ + path: /opt/keycloak/keycloak-22.0.5/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-22.0.4/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-22.0.5/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index f6e24cc..9e3e017 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.4` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.5` | * Service configuration @@ -72,7 +72,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.4` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.5` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 0ae35c1..9aa5531 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 22.0.4 +keycloak_quarkus_version: 22.0.5 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From 9ddd6d7d5e37b13d8ff8fa37f4dd029cbb568af4 Mon Sep 17 00:00:00 2001 From: Antonio Costa Date: Mon, 30 Oct 2023 09:27:30 +0100 Subject: [PATCH 100/376] feat: jboss port offset configuration --- molecule/default/converge.yml | 1 + molecule/default/verify.yml | 5 +++-- roles/keycloak/README.md | 5 +++-- roles/keycloak/defaults/main.yml | 1 + roles/keycloak/meta/argument_specs.yml | 8 ++++++-- .../templates/15.0.8/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/15.0.8/standalone.xml.j2 | 2 +- .../keycloak/templates/9.0.2/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/9.0.2/standalone.xml.j2 | 2 +- roles/keycloak/templates/standalone-ha.xml.j2 | 2 +- roles/keycloak/templates/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/standalone.xml.j2 | 2 +- roles/keycloak/vars/main.yml | 4 ++-- roles/keycloak_realm/meta/argument_specs.yml | 4 ++-- roles/keycloak_realm/vars/main.yml | 4 ++-- 15 files changed, 27 insertions(+), 19 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index d3742e7..e7fd4e0 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -10,6 +10,7 @@ port: 16667 - host: myhost2 port: 16668 + keycloak_jboss_port_offset: 10 roles: - role: keycloak tasks: diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 92a245e..2dfd6a7 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -4,8 +4,9 @@ vars: keycloak_admin_password: "remembertochangeme" keycloak_jvm_package: java-11-openjdk-headless - keycloak_uri: http://localhost:8080 - keycloak_management_port: http://localhost:9990 + keycloak_uri: "http://localhost:{{ 8080 + ( keycloak_jboss_port_offset | default(0) ) }}" + keycloak_management_port: "http://localhost:{{ 9990 + ( keycloak_jboss_port_offset | default(0) ) }}" + keycloak_jboss_port_offset: 10 tasks: - name: Populate service facts ansible.builtin.service_facts: diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index aae309b..13adf35 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -104,14 +104,15 @@ Role Defaults |`keycloak_download_url_9x` | Download URL for keycloak (deprecated) | `https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}` | |`keycloak_installdir` | Installation path | `{{ keycloak_dest }}/keycloak-{{ keycloak_version }}` | |`keycloak_jboss_home` | Installation work directory | `{{ keycloak_rhsso_installdir }}` | +|`keycloak_jboss_port_offset` | Port offset for the JBoss socket binding | `0` | |`keycloak_config_dir` | Path for configuration | `{{ keycloak_jboss_home }}/standalone/configuration` | |`keycloak_config_path_to_standalone_xml` | Custom path for configuration | `{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}` | |`keycloak_config_override_template` | Path to custom template for standalone.xml configuration | `''` | |`keycloak_auth_realm` | Name for rest authentication realm | `master` | |`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` | |`keycloak_force_install` | Remove pre-existing versions of service | `False` | -|`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port }}` | -|`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port }}` | +|`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}` | +|`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}` | |`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `False` | |`keycloak_db_background_validation` | Enable background validation of database connection | `False` | |`keycloak_db_background_validation_millis`| How frequenly the connection pool is validated in the background | `10000` if background validation enabled | diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 9e09804..228d1e6 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -12,6 +12,7 @@ keycloak_jvm_package: java-1.8.0-openjdk-headless keycloak_java_home: keycloak_dest: /opt/keycloak keycloak_jboss_home: "{{ keycloak_installdir }}" +keycloak_jboss_port_offset: 0 keycloak_config_dir: "{{ keycloak_jboss_home }}/standalone/configuration" keycloak_config_standalone_xml: "keycloak.xml" keycloak_config_path_to_standalone_xml: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}" diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index db73f3f..b28be78 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -54,6 +54,10 @@ argument_specs: default: "{{ keycloak_installdir }}" description: "Installation work directory" type: "str" + keycloak_jboss_port_offset: + default: 0 + description: "Port offset for the JBoss socket binding" + type: "int" keycloak_config_dir: # line 26 of keycloak/defaults/main.yml default: "{{ keycloak_jboss_home }}/standalone/configuration" @@ -280,12 +284,12 @@ argument_specs: type: "str" keycloak_url: # line 12 of keycloak/vars/main.yml - default: "http://{{ keycloak_host }}:{{ keycloak_http_port }}" + default: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}" description: "URL for configuration rest calls" type: "str" keycloak_management_url: # line 13 of keycloak/vars/main.yml - default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}" + default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}" description: "URL for management console rest calls" type: "str" keycloak_service_name: diff --git a/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 index be61837..2d84f3f 100644 --- a/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 @@ -737,7 +737,7 @@ - + diff --git a/roles/keycloak/templates/15.0.8/standalone.xml.j2 b/roles/keycloak/templates/15.0.8/standalone.xml.j2 index e2f6a76..de175f2 100644 --- a/roles/keycloak/templates/15.0.8/standalone.xml.j2 +++ b/roles/keycloak/templates/15.0.8/standalone.xml.j2 @@ -638,7 +638,7 @@ - + diff --git a/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 b/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 index 9e0ae66..4f90ad8 100644 --- a/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/9.0.2/standalone-infinispan.xml.j2 @@ -734,7 +734,7 @@ - + diff --git a/roles/keycloak/templates/9.0.2/standalone.xml.j2 b/roles/keycloak/templates/9.0.2/standalone.xml.j2 index 823357f..4188e92 100644 --- a/roles/keycloak/templates/9.0.2/standalone.xml.j2 +++ b/roles/keycloak/templates/9.0.2/standalone.xml.j2 @@ -598,7 +598,7 @@ - + diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 98e26f6..99399f3 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -674,7 +674,7 @@ - + diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 38fbfec..0b0c8af 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -712,7 +712,7 @@ - + diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index bf2d528..72fe4d6 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -604,7 +604,7 @@ - + diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 5fe498d..b03a1a5 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -2,8 +2,8 @@ # internal variables below # locations -keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port }}" -keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}" +keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}" +keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}" keycloak: diff --git a/roles/keycloak_realm/meta/argument_specs.yml b/roles/keycloak_realm/meta/argument_specs.yml index 4345af6..da3eca1 100644 --- a/roles/keycloak_realm/meta/argument_specs.yml +++ b/roles/keycloak_realm/meta/argument_specs.yml @@ -83,12 +83,12 @@ argument_specs: type: "list" keycloak_url: # line 14 of keycloak_realm/vars/main.yml - default: "http://{{ keycloak_host }}:{{ keycloak_http_port }}" + default: "http://{{ keycloak_host }}:{{ keycloak_http_port + ( keycloak_jboss_port_offset | default(0) ) }}" description: "URL for configuration rest calls" type: "str" keycloak_management_url: # line 15 of keycloak_realm/vars/main.yml - default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}" + default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + ( keycloak_jboss_port_offset | default(0) ) }}" description: "URL for management console rest calls" type: "str" downstream: diff --git a/roles/keycloak_realm/vars/main.yml b/roles/keycloak_realm/vars/main.yml index 076a8a9..cbb9435 100644 --- a/roles/keycloak_realm/vars/main.yml +++ b/roles/keycloak_realm/vars/main.yml @@ -5,5 +5,5 @@ keycloak_realm: # other settings -keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port }}" -keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}" +keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + ( keycloak_jboss_port_offset | default(0) ) }}" +keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + ( keycloak_jboss_port_offset | default(0) ) }}" From 363c5d9f9e9ed77f9480df292cfddd1c16234482 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 3 Nov 2023 10:58:25 +0100 Subject: [PATCH 101/376] ddisable new test --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e5a542..50e1fc4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml", "quarkus-devmode", "https_revproxy" ] + [ "default", "quarkus", "overridexml", "quarkus-devmode" ] From 12147b47696c0deae714b06b0678b558f29d3cef Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 25 Oct 2023 18:20:03 +0200 Subject: [PATCH 102/376] linter --- plugins/modules/keycloak_user_federation.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/modules/keycloak_user_federation.py b/plugins/modules/keycloak_user_federation.py index 96f04d7..bc84d8d 100644 --- a/plugins/modules/keycloak_user_federation.py +++ b/plugins/modules/keycloak_user_federation.py @@ -568,7 +568,6 @@ EXAMPLES = ''' realm: my-realm name: my-federation state: absent - ''' RETURN = ''' From a538828f0de9af3afbe8ae06ea84d87d41498ee0 Mon Sep 17 00:00:00 2001 From: Antonio Costa Date: Wed, 25 Oct 2023 16:03:29 +0200 Subject: [PATCH 103/376] feat: add a destination variable for the log link docs: argument specs for the keycloak_quarkus_log_target docs: added parameter to the roles README fix: role variable is keycloak_log_target and not keycloak_quarkus_log_target --- molecule/default/converge.yml | 1 + molecule/default/verify.yml | 28 +++++++++++++++ molecule/quarkus/converge.yml | 1 + molecule/quarkus/verify.yml | 34 +++++++++++++++++++ roles/keycloak/README.md | 2 +- roles/keycloak/defaults/main.yml | 3 ++ roles/keycloak/meta/argument_specs.yml | 4 +++ roles/keycloak/tasks/main.yml | 2 +- roles/keycloak_quarkus/README.md | 1 + roles/keycloak_quarkus/defaults/main.yml | 1 + .../keycloak_quarkus/meta/argument_specs.yml | 4 +++ roles/keycloak_quarkus/tasks/main.yml | 2 +- 12 files changed, 80 insertions(+), 3 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index e7fd4e0..ace4743 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -11,6 +11,7 @@ - host: myhost2 port: 16668 keycloak_jboss_port_offset: 10 + keycloak_log_target: /tmp/keycloak roles: - role: keycloak tasks: diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 2dfd6a7..ba0e01f 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -56,3 +56,31 @@ ansible.builtin.assert: that: - (keycloak_query_clients.json | selectattr('clientId','equalto','TestClient') | first)["attributes"]["post.logout.redirect.uris"] == '/public/logout' + - name: Check log folder + ansible.builtin.stat: + path: "/tmp/keycloak" + register: keycloak_log_folder + - name: Check that keycloak log folder exists and is a link + ansible.builtin.assert: + that: + - keycloak_log_folder.stat.exists + - not keycloak_log_folder.stat.isdir + - keycloak_log_folder.stat.islnk + - name: Check log file + ansible.builtin.stat: + path: "/tmp/keycloak/server.log" + register: keycloak_log_file + - name: Check if keycloak file exists + ansible.builtin.assert: + that: + - keycloak_log_file.stat.exists + - not keycloak_log_file.stat.isdir + - name: Check default log folder + ansible.builtin.stat: + path: "/var/log/keycloak" + register: keycloak_default_log_folder + failed_when: false + - name: Check that default keycloak log folder doesn't exist + ansible.builtin.assert: + that: + - not keycloak_default_log_folder.stat.exists diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 22f9ff4..cb35230 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -11,6 +11,7 @@ keycloak_quarkus_https_enabled: True keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/key.pem" keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/cert.pem" + keycloak_quarkus_log_target: /tmp/keycloak roles: - role: keycloak_quarkus - role: keycloak_realm diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index e956ca6..2d75c32 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -37,3 +37,37 @@ - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/auth' - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/token' delegate_to: localhost + + - name: Check log folder + ansible.builtin.stat: + path: "/tmp/keycloak" + register: keycloak_log_folder + + - name: Check that keycloak log folder exists and is a link + ansible.builtin.assert: + that: + - keycloak_log_folder.stat.exists + - not keycloak_log_folder.stat.isdir + - keycloak_log_folder.stat.islnk + + - name: Check log file + ansible.builtin.stat: + path: "/tmp/keycloak/keycloak.log" + register: keycloak_log_file + + - name: Check if keycloak file exists + ansible.builtin.assert: + that: + - keycloak_log_file.stat.exists + - not keycloak_log_file.stat.isdir + + - name: Check default log folder + ansible.builtin.stat: + path: "/var/log/keycloak" + register: keycloak_default_log_folder + failed_when: false + + - name: Check that default keycloak log folder doesn't exist + ansible.builtin.assert: + that: + - not keycloak_default_log_folder.stat.exists diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 13adf35..17149f7 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -118,7 +118,7 @@ Role Defaults |`keycloak_db_background_validation_millis`| How frequenly the connection pool is validated in the background | `10000` if background validation enabled | |`keycloak_db_background_validate_on_match` | Enable validate on match for database connections | `False` | |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | - +|`keycloak_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | Role Variables diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 228d1e6..2b5cc35 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -115,3 +115,6 @@ keycloak_default_jdbc: version: 12.2.0 # role specific vars keycloak_no_log: True + +### logging configuration +keycloak_log_target: /var/log/keycloak diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index b28be78..2e93667 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -360,6 +360,10 @@ argument_specs: required: False description: "Override the subnet match for jgroups cluster formation; if not defined, it will be inferred from local machine route configuration" type: "str" + keycloak_log_target: + default: '/var/log/keycloak' + type: "str" + description: "Set the destination of the keycloak log folder link" downstream: options: sso_version: diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index 32aca04..7fe0222 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -34,7 +34,7 @@ ansible.builtin.file: state: link src: "{{ keycloak_jboss_home }}/standalone/log" - dest: /var/log/keycloak + dest: "{{ keycloak_log_target }}" become: yes - name: Set admin credentials and restart if not already created diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index f6e24cc..0ea2648 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -97,6 +97,7 @@ Role Defaults |`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` | |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | |`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | +|`keycloak_quarkus_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 0ae35c1..7995d05 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -90,3 +90,4 @@ keycloak_quarkus_log: file keycloak_quarkus_log_level: info keycloak_quarkus_log_file: data/log/keycloak.log keycloak_quarkus_log_format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' +keycloak_quarkus_log_target: /var/log/keycloak diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 59f3e50..32e550b 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -243,6 +243,10 @@ argument_specs: default: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' type: "str" description: "Set a format specific to file log entries" + keycloak_quarkus_log_target: + default: '/var/log/keycloak' + type: "str" + description: "Set the destination of the keycloak log folder link" keycloak_quarkus_proxy_mode: default: 'edge' type: "str" diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index a86a4f5..43cbb38 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -67,6 +67,6 @@ ansible.builtin.file: state: link src: "{{ keycloak.log.file | dirname }}" - dest: /var/log/keycloak + dest: "{{ keycloak_quarkus_log_target }}" force: yes become: yes From 62e5380d383dea6e2d195340d89fd53a5f2c9cbc Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:32:15 +0200 Subject: [PATCH 104/376] Update Keycloak to version 22.0.5 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index f9fe2b7..f90564c 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -19,13 +19,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-22.0.4/conf/ + path: /opt/keycloak/keycloak-22.0.5/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-22.0.4/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-22.0.5/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 0ea2648..1a50a00 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.4` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.5` | * Service configuration @@ -72,7 +72,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.4` | +|`keycloak_quarkus_version`| keycloak.org package version | `22.0.5` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 7995d05..d769a85 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 22.0.4 +keycloak_quarkus_version: 22.0.5 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From 03175e283b50f4d1e21ce5dfb7cad78650f0e9d7 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 25 Oct 2023 16:40:25 +0200 Subject: [PATCH 105/376] molecule test for keycloakx with proxy --- .github/workflows/ci.yml | 2 +- molecule/https_revproxy/converge.yml | 16 ++++++++ molecule/https_revproxy/molecule.yml | 59 ++++++++++++++++++++++++++++ molecule/https_revproxy/prepare.yml | 49 +++++++++++++++++++++++ molecule/https_revproxy/roles | 1 + molecule/https_revproxy/verify.yml | 39 ++++++++++++++++++ molecule/requirements.yml | 2 +- 7 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 molecule/https_revproxy/converge.yml create mode 100644 molecule/https_revproxy/molecule.yml create mode 100644 molecule/https_revproxy/prepare.yml create mode 120000 molecule/https_revproxy/roles create mode 100644 molecule/https_revproxy/verify.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50e1fc4..6e5a542 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml", "quarkus-devmode" ] + [ "default", "quarkus", "overridexml", "quarkus-devmode", "https_revproxy" ] diff --git a/molecule/https_revproxy/converge.yml b/molecule/https_revproxy/converge.yml new file mode 100644 index 0000000..b1eb7bc --- /dev/null +++ b/molecule/https_revproxy/converge.yml @@ -0,0 +1,16 @@ +--- +- name: Converge + hosts: all + vars: + keycloak_quarkus_admin_pass: "remembertochangeme" + keycloak_admin_password: "remembertochangeme" + keycloak_realm: TestRealm + keycloak_quarkus_host: instance + keycloak_quarkus_log: file + keycloak_quarkus_http_enabled: True + keycloak_quarkus_http_port: 8080 + keycloak_quarkus_proxy_mode: edge + keycloak_quarkus_http_relative_path: / + keycloak_quarkus_frontend_url: https://proxy/ + roles: + - role: keycloak_quarkus diff --git a/molecule/https_revproxy/molecule.yml b/molecule/https_revproxy/molecule.yml new file mode 100644 index 0000000..efdebf4 --- /dev/null +++ b/molecule/https_revproxy/molecule.yml @@ -0,0 +1,59 @@ +--- +driver: + name: docker +platforms: + - name: instance + image: registry.access.redhat.com/ubi8/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + networks: + - name: keycloak + port_bindings: + - "8080/tcp" + published_ports: + - 0.0.0.0:8080:8080/tcp + - name: proxy + image: registry.access.redhat.com/ubi8/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + networks: + - name: keycloak + port_bindings: + - "443/tcp" + published_ports: + - 0.0.0.0:443:443/tcp +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + ssh_connection: + pipelining: false + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + env: + ANSIBLE_FORCE_COLOR: "true" + REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID: "${REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID}" + REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET: "${REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET}" +verifier: + name: ansible +scenario: + test_sequence: + - cleanup + - destroy + - create + - prepare + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/https_revproxy/prepare.yml b/molecule/https_revproxy/prepare.yml new file mode 100644 index 0000000..5cdb135 --- /dev/null +++ b/molecule/https_revproxy/prepare.yml @@ -0,0 +1,49 @@ +--- +- name: Prepare + hosts: all + tasks: + - name: Install sudo + ansible.builtin.yum: + name: sudo + state: present + + - name: "Display hera_home if defined." + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + +- name: Prepare proxy + hosts: proxy + vars: + jbcs_mod_cluster_enable: True + jbcs_configure_firewalld: False + jbcs_offline_install: False + jbcs_bind_address: '*' + jbcs_proxy_pass: + - path: / + url: http://instance:8080/ + reverse_path: / + reverse_url: http://instance:8080/ + external_domain_name: proxy + rhn_username: "{{ lookup('env', 'REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID') }}" + rhn_password: "{{ lookup('env', 'REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET') }}" + roles: + - middleware_automation.jbcs.jbcs + pre_tasks: + - name: Create certificate request + ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=proxy' + delegate_to: localhost + changed_when: False + + - name: Copy certificates + ansible.builtin.copy: + src: "{{ item.name }}" + dest: "{{ item.dest }}" + mode: 0444 + become: True + loop: + - { name: 'cert.pem', dest: '/etc/pki/tls/certs/proxy.crt' } + - { name: 'key.pem', dest: '/etc/pki/tls/private/proxy.key' } + + - name: update_ca_trust + command: update-ca-trust + become: True diff --git a/molecule/https_revproxy/roles b/molecule/https_revproxy/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/https_revproxy/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/molecule/https_revproxy/verify.yml b/molecule/https_revproxy/verify.yml new file mode 100644 index 0000000..9d355a6 --- /dev/null +++ b/molecule/https_revproxy/verify.yml @@ -0,0 +1,39 @@ +--- +- name: Verify + hosts: all + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + + - name: Check if keycloak service started + ansible.builtin.assert: + that: + - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" + + - name: Set internal envvar + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - name: Verify openid config + block: + - name: Fetch openID config # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + curl https://localhost:443/realms/master/.well-known/openid-configuration -k | jq . + args: + executable: /bin/bash + register: openid_config + changed_when: False + delegate_to: localhost + - name: Verify endpoint URLs + ansible.builtin.assert: + that: + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://proxy/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'https://proxy/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/token' + delegate_to: localhost + when: + - hera_home is defined + - hera_home | length == 0 diff --git a/molecule/requirements.yml b/molecule/requirements.yml index 2e0ae56..5e39b59 100644 --- a/molecule/requirements.yml +++ b/molecule/requirements.yml @@ -1,8 +1,8 @@ --- collections: - name: middleware_automation.common + - name: middleware_automation.jbcs - name: community.general - name: ansible.posix - name: community.docker version: ">=1.9.1" - From 61730b981b7b18f138d7e16d30890240fc57113b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 3 Nov 2023 10:58:25 +0100 Subject: [PATCH 106/376] ddisable new test --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e5a542..50e1fc4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml", "quarkus-devmode", "https_revproxy" ] + [ "default", "quarkus", "overridexml", "quarkus-devmode" ] From 5543217c6a71df77818b0ffd5553e059dbfab7b4 Mon Sep 17 00:00:00 2001 From: Antonio Costa Date: Mon, 6 Nov 2023 15:00:51 +0100 Subject: [PATCH 107/376] rebase for changes made in PR 120 --- molecule/default/converge.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index ace4743..1e817f6 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -12,6 +12,7 @@ port: 16668 keycloak_jboss_port_offset: 10 keycloak_log_target: /tmp/keycloak + keycloak_jboss_port_offset: 10 roles: - role: keycloak tasks: From 316cde47596484300eaedfa09ad48b9af0f5ba3a Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Mon, 9 Oct 2023 09:59:51 +0200 Subject: [PATCH 108/376] Add support for more http-related configs * keycloak_quarkus_http_relative_path var now populate http-relative-path config [breaking change] * http-relative-path defaults to / [breaking change] * enable configuration of hostname-url and hostname-admin-url --- molecule/quarkus-devmode/converge.yml | 1 - molecule/quarkus/converge.yml | 1 - roles/keycloak_quarkus/README.md | 6 ++++-- roles/keycloak_quarkus/defaults/main.yml | 8 ++++++-- roles/keycloak_quarkus/meta/argument_specs.yml | 12 +++++++++--- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 10 ++++++++-- 6 files changed, 27 insertions(+), 11 deletions(-) diff --git a/molecule/quarkus-devmode/converge.yml b/molecule/quarkus-devmode/converge.yml index b484120..6cbe7d8 100644 --- a/molecule/quarkus-devmode/converge.yml +++ b/molecule/quarkus-devmode/converge.yml @@ -5,7 +5,6 @@ keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_admin_password: "remembertochangeme" keycloak_realm: TestRealm - keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file keycloak_quarkus_frontend_url: 'http://localhost:8080/' keycloak_quarkus_start_dev: True diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index cb35230..43e2215 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -6,7 +6,6 @@ keycloak_admin_password: "remembertochangeme" keycloak_realm: TestRealm keycloak_quarkus_host: instance - keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file keycloak_quarkus_https_enabled: True keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/key.pem" diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 1a50a00..7108780 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -24,6 +24,7 @@ Role Defaults |`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | |`keycloak_quarkus_host`| Hostname for the Keycloak server | `localhost` | |`keycloak_quarkus_port`| The port used by the proxy when exposing the hostname | `-1` | +|`keycloak_quarkus_path`| This should be set if proxy uses a different context-path for Keycloak | | |`keycloak_quarkus_http_port`| HTTP listening port | `8080` | |`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` | @@ -34,8 +35,9 @@ Role Defaults |`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | |`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | -|`keycloak_quarkus_frontend_url`| Service public URL | `http://localhost:8080/auth` | -|`keycloak_quarkus_http_relative_path` | Service context path | `auth` | +|`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | | +|`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | | +|`keycloak_quarkus_http_relative_path` | Service context path | | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | |`keycloak_quarkus_https_enabled`| Enable listener on HTTPS port | `False` | |`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `{{ keycloak.home }}/conf/server.key.pem` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index d769a85..62cd05e 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -29,6 +29,7 @@ keycloak_quarkus_master_realm: master keycloak_quarkus_bind_address: 0.0.0.0 keycloak_quarkus_host: localhost keycloak_quarkus_port: -1 +keycloak_quarkus_path: '' keycloak_quarkus_http_enabled: True keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 @@ -47,8 +48,11 @@ keycloak_quarkus_ha_enabled: False keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False }}" ### keycloak frontend url -keycloak_quarkus_http_relative_path: auth -keycloak_quarkus_frontend_url: http://localhost:8080/auth +keycloak_quarkus_frontend_url: '' +keycloak_quarkus_admin_url: '' + +### path under the application is exposed (set to `auth` for retrocompatibility with pre-quarkus releases) +keycloak_quarkus_http_relative_path: '' # proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 32e550b..2dd32bb 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -97,6 +97,10 @@ argument_specs: default: -1 description: "The port used by the proxy when exposing the hostname" type: "int" + keycloak_quarkus_path: + default: "" + description: "This should be set if proxy uses a different context-path for Keycloak" + type: "str" keycloak_quarkus_http_enabled: default: true description: "Enable listener on HTTP port" @@ -149,14 +153,16 @@ argument_specs: description: "Enable auto configuration for database backend" type: "str" keycloak_quarkus_http_relative_path: - # line 41 of defaults/main.yml default: "auth" description: "Service context path" type: "str" keycloak_quarkus_frontend_url: - # line 41 of defaults/main.yml - default: "http://localhost:8080/auth" description: "Service public URL" + default: "" + type: "str" + keycloak_quarkus_admin_url: + description: "Service URL for the admin console" + default: "" type: "str" keycloak_quarkus_metrics_enabled: # line 43 of defaults/main.yml diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 7285c48..e2c078a 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -15,6 +15,7 @@ health-enabled={{ keycloak_quarkus_health_enabled }} # HTTP http-enabled={{ keycloak_quarkus_http_enabled }} http-port={{ keycloak_quarkus_http_port }} +http-relative-path={{ keycloak_quarkus_http_relative_path }} # HTTPS https-port={{ keycloak_quarkus_https_port }} @@ -23,10 +24,15 @@ https-certificate-file={{ keycloak_quarkus_cert_file}} https-certificate-key-file={{ keycloak_quarkus_key_file }} {% endif %} -# Hostname for the Keycloak server. +# Client URL configuration +{% if keycloak_quarkus_frontend_url %} +hostname-url={{ keycloak_quarkus_frontend_url }} +{% else %} hostname={{ keycloak_quarkus_host }} hostname-port={{ keycloak_quarkus_port }} -hostname-path={{ keycloak_quarkus_http_relative_path }} +hostname-path={{ keycloak_quarkus_path }} +{% endif %} +hostname-admin-url={{ keycloak_quarkus_admin_url }} # Cluster {% if keycloak_quarkus_ha_enabled %} From 8eb518528743fb2da8a15cc655b1e4ee8319eb42 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Wed, 25 Oct 2023 10:46:52 +0200 Subject: [PATCH 109/376] use relative path to build health url --- roles/keycloak_quarkus/vars/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index 1b3ef73..c3a9623 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,7 +4,7 @@ keycloak: config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}/realms/master/.well-known/openid-configuration" + health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}/{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path else '' }}realms/master/.well-known/openid-configuration" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" From c8f968a5873e29e014aa7ccd1117f8e2748c8797 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Fri, 27 Oct 2023 15:42:42 +0200 Subject: [PATCH 110/376] cleanup vars --- roles/keycloak_quarkus/defaults/main.yml | 10 +++++----- roles/keycloak_quarkus/meta/argument_specs.yml | 14 ++++++-------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 62cd05e..b38e921 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -22,14 +22,14 @@ keycloak_quarkus_configure_firewalld: False ### administrator console password keycloak_quarkus_admin_user: admin -keycloak_quarkus_admin_pass: '' +keycloak_quarkus_admin_pass: keycloak_quarkus_master_realm: master ### Configuration settings keycloak_quarkus_bind_address: 0.0.0.0 keycloak_quarkus_host: localhost keycloak_quarkus_port: -1 -keycloak_quarkus_path: '' +keycloak_quarkus_path: keycloak_quarkus_http_enabled: True keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 @@ -48,11 +48,11 @@ keycloak_quarkus_ha_enabled: False keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False }}" ### keycloak frontend url -keycloak_quarkus_frontend_url: '' -keycloak_quarkus_admin_url: '' +keycloak_quarkus_frontend_url: +keycloak_quarkus_admin_url: ### path under the application is exposed (set to `auth` for retrocompatibility with pre-quarkus releases) -keycloak_quarkus_http_relative_path: '' +keycloak_quarkus_http_relative_path: # proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 2dd32bb..9855aa5 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -70,13 +70,11 @@ argument_specs: description: "Ensure firewalld is running and configure keycloak ports" type: "bool" keycloak_quarkus_admin_user: - # line 22 of defaults/main.yml default: "admin" description: "Administration console user account" type: "str" keycloak_quarkus_admin_pass: - # line 23 of defaults/main.yml - default: "" + required: true description: "Password of console admin account" type: "str" keycloak_quarkus_master_realm: @@ -98,13 +96,13 @@ argument_specs: description: "The port used by the proxy when exposing the hostname" type: "int" keycloak_quarkus_path: - default: "" + required: false description: "This should be set if proxy uses a different context-path for Keycloak" type: "str" keycloak_quarkus_http_enabled: default: true description: "Enable listener on HTTP port" - type: "bool" + type: "bool" keycloak_quarkus_http_port: # line 29 of defaults/main.yml default: 8080 @@ -153,16 +151,16 @@ argument_specs: description: "Enable auto configuration for database backend" type: "str" keycloak_quarkus_http_relative_path: - default: "auth" + required: false description: "Service context path" type: "str" keycloak_quarkus_frontend_url: + required: false description: "Service public URL" - default: "" type: "str" keycloak_quarkus_admin_url: + required: false description: "Service URL for the admin console" - default: "" type: "str" keycloak_quarkus_metrics_enabled: # line 43 of defaults/main.yml From 880d70ffb988bc51d4db32188bc9ebf9e1e8f171 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Tue, 7 Nov 2023 10:21:05 +0100 Subject: [PATCH 111/376] enable https_revproxy test --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50e1fc4..6e5a542 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml", "quarkus-devmode" ] + [ "default", "quarkus", "overridexml", "quarkus-devmode", "https_revproxy" ] From 0e510c093a3fbd9d2b964ed39f71eefd968b2522 Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Mon, 13 Nov 2023 10:07:01 +0100 Subject: [PATCH 112/376] Set default keycloak_quarkus_http_relative_path as per upstream docs --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 5 +++-- roles/keycloak_quarkus/meta/argument_specs.yml | 3 ++- roles/keycloak_quarkus/vars/main.yml | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 7108780..30e7cd8 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -37,7 +37,7 @@ Role Defaults |`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | |`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | | |`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | | -|`keycloak_quarkus_http_relative_path` | Service context path | | +|`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | |`keycloak_quarkus_https_enabled`| Enable listener on HTTPS port | `False` | |`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `{{ keycloak.home }}/conf/server.key.pem` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index b38e921..e28d16f 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -51,8 +51,9 @@ keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False keycloak_quarkus_frontend_url: keycloak_quarkus_admin_url: -### path under the application is exposed (set to `auth` for retrocompatibility with pre-quarkus releases) -keycloak_quarkus_http_relative_path: +### Set the path relative to / for serving resources. The path must start with a / +### (set to `/auth` for retrocompatibility with pre-quarkus releases) +keycloak_quarkus_http_relative_path: / # proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 9855aa5..9f5d9de 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -152,7 +152,8 @@ argument_specs: type: "str" keycloak_quarkus_http_relative_path: required: false - description: "Service context path" + default: / + description: "Set the path relative to / for serving resources. The path must start with a /" type: "str" keycloak_quarkus_frontend_url: required: false diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index c3a9623..0ef6844 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,7 +4,7 @@ keycloak: config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}/{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path else '' }}realms/master/.well-known/openid-configuration" + health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" From ea086e8a6231b07074e4dcb5c9bf8b54f2e00e78 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 13 Nov 2023 11:37:18 +0100 Subject: [PATCH 113/376] ci: add missing header to molecule test --- molecule/https_revproxy/verify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/molecule/https_revproxy/verify.yml b/molecule/https_revproxy/verify.yml index 9d355a6..112a460 100644 --- a/molecule/https_revproxy/verify.yml +++ b/molecule/https_revproxy/verify.yml @@ -20,7 +20,7 @@ - name: Fetch openID config # noqa blocked_modules command-instead-of-module ansible.builtin.shell: | set -o pipefail - curl https://localhost:443/realms/master/.well-known/openid-configuration -k | jq . + curl https://localhost:443/realms/master/.well-known/openid-configuration -H "Host: proxy" -k | jq . args: executable: /bin/bash register: openid_config From 7a1eeec6b60f0e92a5840e803a5491c280495c3d Mon Sep 17 00:00:00 2001 From: Ranabir Chakraborty Date: Mon, 13 Nov 2023 18:18:52 +0530 Subject: [PATCH 114/376] AMWSUP-17 keycloak Ansible Hub documentation link broken --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d93231f..30d6d9e 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,13 @@ A requirement file is provided to install: pip install -r requirements.txt - + ### Included roles * [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service. * [`keycloak_realm`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md): role for configuring a realm, user federation(s), clients and users, in an installed service. * [`keycloak_quarkus`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_quarkus/README.md): role for installing the quarkus variant of keycloak (>= 17.0.0). - + ## Usage From 49c507173347a8bcab4d470660e36989113d353e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 13 Nov 2023 16:37:58 +0100 Subject: [PATCH 115/376] ci: fix envvars --- molecule/https_revproxy/molecule.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/molecule/https_revproxy/molecule.yml b/molecule/https_revproxy/molecule.yml index efdebf4..6a8790d 100644 --- a/molecule/https_revproxy/molecule.yml +++ b/molecule/https_revproxy/molecule.yml @@ -41,8 +41,8 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" - REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID: "${REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID}" - REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET: "${REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET}" + REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID: "${PROD_JBOSSNETWORK_API_CLIENTID}" + REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET: "${PROD_JBOSSNETWORK_API_SECRET}" verifier: name: ansible scenario: From a0f6a4931f0bdebfe5c9e094253e403091f4ee7b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 13 Nov 2023 16:47:03 +0100 Subject: [PATCH 116/376] ci: https_revproxy molecule verify step --- molecule/https_revproxy/verify.yml | 2 +- roles/keycloak/tasks/fastpackages.yml | 21 ++++++++--------- roles/keycloak_quarkus/tasks/fastpackages.yml | 23 ++++++++----------- 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/molecule/https_revproxy/verify.yml b/molecule/https_revproxy/verify.yml index 112a460..2f31ec3 100644 --- a/molecule/https_revproxy/verify.yml +++ b/molecule/https_revproxy/verify.yml @@ -20,7 +20,7 @@ - name: Fetch openID config # noqa blocked_modules command-instead-of-module ansible.builtin.shell: | set -o pipefail - curl https://localhost:443/realms/master/.well-known/openid-configuration -H "Host: proxy" -k | jq . + curl https://localhost:443/realms/master/.well-known/openid-configuration -H "Host: proxy" -k -s | jq . args: executable: /bin/bash register: openid_config diff --git a/roles/keycloak/tasks/fastpackages.yml b/roles/keycloak/tasks/fastpackages.yml index 17d103e..cfd9025 100644 --- a/roles/keycloak/tasks/fastpackages.yml +++ b/roles/keycloak/tasks/fastpackages.yml @@ -1,19 +1,16 @@ --- -- name: Check packages to be installed - block: - - name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster - ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" - register: rpm_info - changed_when: rpm_info.failed +- name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster + ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" + register: rpm_info + changed_when: False + failed_when: False - rescue: - - name: "Add missing packages to the yum install list" - ansible.builtin.set_fact: - packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | flatten }}" - when: rpm_info.failed +- name: "Add missing packages to the yum install list" + ansible.builtin.set_fact: + packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" - name: "Install packages: {{ packages_to_install }}" - become: yes + become: True ansible.builtin.yum: name: "{{ packages_to_install }}" state: present diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml index 78472dd..cfd9025 100644 --- a/roles/keycloak_quarkus/tasks/fastpackages.yml +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -1,19 +1,16 @@ --- -- name: Check packages to be installed - block: - - name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster - ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" - register: rpm_info - changed_when: rpm_info.failed +- name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster + ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" + register: rpm_info + changed_when: False + failed_when: False - rescue: - - name: "Add missing packages to the yum install list" - ansible.builtin.set_fact: - packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | flatten }}" - when: rpm_info.failed +- name: "Add missing packages to the yum install list" + ansible.builtin.set_fact: + packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" -- name: "Install packages: {{ packages_to_install | join(',') }}" - become: yes +- name: "Install packages: {{ packages_to_install }}" + become: True ansible.builtin.yum: name: "{{ packages_to_install }}" state: present From 8af5d6e55605928028600002c945dd6dafa649fa Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 13 Nov 2023 18:10:40 +0100 Subject: [PATCH 117/376] ci: https_revproxy molecule verify step --- molecule/https_revproxy/verify.yml | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/molecule/https_revproxy/verify.yml b/molecule/https_revproxy/verify.yml index 2f31ec3..2c8befb 100644 --- a/molecule/https_revproxy/verify.yml +++ b/molecule/https_revproxy/verify.yml @@ -11,29 +11,23 @@ - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" - - name: Set internal envvar - ansible.builtin.set_fact: - hera_home: "{{ lookup('env', 'HERA_HOME') }}" - - name: Verify openid config + run_once: True block: - name: Fetch openID config # noqa blocked_modules command-instead-of-module - ansible.builtin.shell: | - set -o pipefail - curl https://localhost:443/realms/master/.well-known/openid-configuration -H "Host: proxy" -k -s | jq . - args: - executable: /bin/bash + ansible.builtin.uri: + url: https://localhost:443/realms/master/.well-known/openid-configuration + validate_certs: false + headers: + Host: proxy register: openid_config changed_when: False delegate_to: localhost - name: Verify endpoint URLs ansible.builtin.assert: that: - - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://proxy/realms/master/protocol/openid-connect/ext/ciba/auth' - - (openid_config.stdout | from_json)['issuer'] == 'https://proxy/realms/master' - - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/auth' - - (openid_config.stdout | from_json)['token_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/token' + - openid_config.json["backchannel_authentication_endpoint"] == 'https://proxy/realms/master/protocol/openid-connect/ext/ciba/auth' + - openid_config.json['issuer'] == 'https://proxy/realms/master' + - openid_config.json['authorization_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/auth' + - openid_config.json['token_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/token' delegate_to: localhost - when: - - hera_home is defined - - hera_home | length == 0 From efc3e547feee845f99fd3195ad6e682824f5fe77 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 13 Nov 2023 18:24:06 +0100 Subject: [PATCH 118/376] ci: https_revproxy molecule verify step --- molecule/https_revproxy/verify.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/molecule/https_revproxy/verify.yml b/molecule/https_revproxy/verify.yml index 2c8befb..4a69cb2 100644 --- a/molecule/https_revproxy/verify.yml +++ b/molecule/https_revproxy/verify.yml @@ -1,6 +1,6 @@ --- - name: Verify - hosts: all + hosts: instance tasks: - name: Populate service facts ansible.builtin.service_facts: @@ -12,22 +12,17 @@ - ansible_facts.services["keycloak.service"]["status"] == "enabled" - name: Verify openid config - run_once: True block: - name: Fetch openID config # noqa blocked_modules command-instead-of-module ansible.builtin.uri: - url: https://localhost:443/realms/master/.well-known/openid-configuration + url: http://localhost:8080/realms/master/.well-known/openid-configuration validate_certs: false headers: Host: proxy register: openid_config changed_when: False - delegate_to: localhost - name: Verify endpoint URLs ansible.builtin.assert: that: - - openid_config.json["backchannel_authentication_endpoint"] == 'https://proxy/realms/master/protocol/openid-connect/ext/ciba/auth' - openid_config.json['issuer'] == 'https://proxy/realms/master' - openid_config.json['authorization_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/auth' - - openid_config.json['token_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/token' - delegate_to: localhost From 143084d726babae6c0611cb9f4508efbea3a5481 Mon Sep 17 00:00:00 2001 From: Jake Muff <67475147+JMuff22@users.noreply.github.com> Date: Thu, 16 Nov 2023 10:19:47 +0200 Subject: [PATCH 119/376] Update admin password variable in keycloak_quarkus.yml --- playbooks/keycloak_quarkus.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index 5d34c87..5b1122a 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -2,7 +2,7 @@ - name: Playbook for Keycloak X Hosts with HTTPS enabled hosts: all vars: - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_quarkus_host: localhost keycloak_quarkus_port: 8443 keycloak_quarkus_http_relative_path: '' From 2841c7a95148c29c7e7625f04754d0bc77f9021a Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Mon, 20 Nov 2023 17:10:43 +0000 Subject: [PATCH 120/376] Update changelog for release 2.0.0 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 16 ++++++++++++++++ changelogs/changelog.yaml | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8bcfa45..fa6fdea 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,22 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.0.0 +====== + +Minor Changes +------------- + +- Add new parameter for port offset configuration `#124 `_ +- Update Keycloak to version 22.0.5 `#122 `_ + +Breaking Changes / Porting Guide +-------------------------------- + +- Add support for more http-related configs `#115 `_ +- Update minimum ansible-core version > 2.14 `#119 `_ +- keycloak_quarkus: enable config of key store and trust store `#116 `_ + v1.3.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index c3b1994..e3ec06e 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -315,3 +315,29 @@ releases: - 112.yaml - 113.yaml release_date: '2023-09-25' + 2.0.0: + changes: + breaking_changes: + - 'Add support for more http-related configs `#115 `_ + + ' + - 'Update minimum ansible-core version > 2.14 `#119 `_ + + ' + - 'keycloak_quarkus: enable config of key store and trust store `#116 `_ + + ' + minor_changes: + - 'Add new parameter for port offset configuration `#124 `_ + + ' + - 'Update Keycloak to version 22.0.5 `#122 `_ + + ' + fragments: + - 115.yaml + - 116.yaml + - 119.yaml + - 122.yaml + - 124.yaml + release_date: '2023-11-20' From e086ee8d29091416fbcb3a36c4f803edd01c0175 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Mon, 20 Nov 2023 17:10:52 +0000 Subject: [PATCH 121/376] Bump version to 2.0.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index ef8da0d..bd77fe6 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.0.0" +version: "2.0.1" readme: README.md authors: - Romain Pelisse From a439ccab5e067efe73f6ebd0c1cd11c1fd4e3254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=A2d=20Bouryaln?= <74252238+saadsb20@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:36:00 +0100 Subject: [PATCH 122/376] fix health_url --- roles/keycloak_quarkus/vars/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index 0ef6844..991bdeb 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,7 +4,7 @@ keycloak: config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" + health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}/{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" From 3a1d9099a76cee864d334d0c687b72d594ddbff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=A2d=20Bouryaln?= <74252238+saadsb20@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:01:49 +0100 Subject: [PATCH 123/376] reverte change --- roles/keycloak_quarkus/vars/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index 991bdeb..0ef6844 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,7 +4,7 @@ keycloak: config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}/{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" + health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" From 88935abb62444a7392ec2030a5a5c1b0e95f747b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=A2d=20Bouryaln?= <74252238+saadsb20@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:26:22 +0100 Subject: [PATCH 124/376] Validate relative path validate the relative path ... must begin with / --- roles/keycloak_quarkus/tasks/prereqs.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 4040d8f..be807df 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -6,6 +6,14 @@ quiet: True fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass variable to a 12+ char long string" success_msg: "{{ 'Console administrator password OK' }}" + +- name: Validate relative path + ansible.builtin.assert: + that: + - keycloak_quarkus_http_relative_path is regex('^/.*') + quiet: True + fail_msg: "the relative path must begin with /" + success_msg: "{{ 'relative path OK' }}" - name: Validate configuration ansible.builtin.assert: From 55c02d7fc5768385c2d60b5219cc7343076df4ae Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Fri, 1 Dec 2023 10:34:04 +0100 Subject: [PATCH 125/376] Update Keycloak to version 23.0.1 --- molecule/quarkus/prepare.yml | 4 ++-- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index f90564c..44d2492 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -19,13 +19,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-22.0.5/conf/ + path: /opt/keycloak/keycloak-23.0.1/conf/ mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-22.0.5/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-23.0.1/conf/{{ item }}" mode: 0444 loop: - cert.pem diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index c2338c3..c32054e 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.5` | +|`keycloak_quarkus_version`| keycloak.org package version | `23.0.1` | * Service configuration @@ -81,7 +81,7 @@ Role Defaults |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| -|`keycloak_quarkus_version`| keycloak.org package version | `22.0.5` | +|`keycloak_quarkus_version`| keycloak.org package version | `23.0.1` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 51ca792..4a89be6 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 22.0.5 +keycloak_quarkus_version: 23.0.1 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From d6f020ab44aebc13da10c04660c6869ae7075105 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 1 Dec 2023 12:36:20 +0100 Subject: [PATCH 126/376] linter fixes --- README.md | 4 +- meta/runtime.yml | 2 +- playbooks/keycloak_federation.yml | 14 ++--- playbooks/keycloak_quarkus.yml | 2 +- playbooks/keycloak_realm.yml | 14 ++--- playbooks/rhsso.yml | 2 +- roles/keycloak/README.md | 30 +++++----- roles/keycloak/defaults/main.yml | 24 ++++---- roles/keycloak/meta/argument_specs.yml | 20 +++---- roles/keycloak/meta/main.yml | 6 +- roles/keycloak/tasks/fastpackages.yml | 6 +- roles/keycloak/tasks/firewalld.yml | 10 ++-- roles/keycloak/tasks/install.yml | 56 +++++++++---------- roles/keycloak/tasks/jdbc_driver.yml | 10 ++-- roles/keycloak/tasks/main.yml | 8 +-- roles/keycloak/tasks/prereqs.yml | 8 +-- roles/keycloak/tasks/restart_keycloak.yml | 11 ++-- roles/keycloak/tasks/rhsso_patch.yml | 30 +++++----- roles/keycloak/tasks/start_keycloak.yml | 5 +- roles/keycloak/tasks/stop_keycloak.yml | 4 +- roles/keycloak/tasks/systemd.yml | 16 ++---- roles/keycloak_quarkus/defaults/main.yml | 24 ++++---- .../keycloak_quarkus/meta/argument_specs.yml | 12 ++-- roles/keycloak_quarkus/meta/main.yml | 6 +- roles/keycloak_quarkus/tasks/fastpackages.yml | 6 +- roles/keycloak_quarkus/tasks/firewalld.yml | 8 +-- roles/keycloak_quarkus/tasks/install.yml | 18 +++--- roles/keycloak_quarkus/tasks/main.yml | 12 ++-- roles/keycloak_quarkus/tasks/prereqs.yml | 6 +- roles/keycloak_quarkus/tasks/restart.yml | 5 +- roles/keycloak_quarkus/tasks/start.yml | 5 +- roles/keycloak_quarkus/tasks/systemd.yml | 10 +--- roles/keycloak_realm/defaults/main.yml | 2 +- roles/keycloak_realm/meta/argument_specs.yml | 6 +- roles/keycloak_realm/meta/main.yml | 6 +- roles/keycloak_realm/tasks/main.yml | 6 +- roles/keycloak_realm/tasks/manage_user.yml | 8 +-- .../tasks/manage_user_client_roles.yml | 2 +- .../tasks/manage_user_roles.yml | 4 +- roles/keycloak_realm/vars/main.yml | 4 +- 40 files changed, 212 insertions(+), 220 deletions(-) diff --git a/README.md b/README.md index 30d6d9e..2c04254 100644 --- a/README.md +++ b/README.md @@ -66,11 +66,11 @@ For full service configuration details, refer to the [keycloak role README](http #### Install from controller node (offline) -Making the keycloak zip archive available to the playbook working directory, and setting `keycloak_offline_install` to `True`, allows to skip +Making the keycloak zip archive available to the playbook working directory, and setting `keycloak_offline_install` to `true`, allows to skip the download tasks. The local path for the archive does match the downloaded archive path, so that it is also used as a cache when multiple hosts are provisioned in a cluster. ```yaml -keycloak_offline_install: True +keycloak_offline_install: true ``` diff --git a/meta/runtime.yml b/meta/runtime.yml index 47dc0fb..ce6befd 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1,2 +1,2 @@ --- -requires_ansible: ">=2.14.0" \ No newline at end of file +requires_ansible: ">=2.14.0" diff --git a/playbooks/keycloak_federation.yml b/playbooks/keycloak_federation.yml index f6de6c1..49cb6c0 100644 --- a/playbooks/keycloak_federation.yml +++ b/playbooks/keycloak_federation.yml @@ -55,14 +55,14 @@ - TestClient1Admin - TestClient1User realm: "{{ keycloak_realm }}" - public_client: True + public_client: true web_origins: - http://testclient1origin/application - http://testclient1origin/other users: - - username: TestUser - password: password - client_roles: - - client: TestClient1 - role: TestClient1User - realm: "{{ keycloak_realm }}" + - username: TestUser + password: password + client_roles: + - client: TestClient1 + role: TestClient1User + realm: "{{ keycloak_realm }}" diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index 5b1122a..13bbce5 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -7,7 +7,7 @@ keycloak_quarkus_port: 8443 keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file - keycloak_quarkus_https_key_file_enabled: True + keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_key_file: conf/key.pem keycloak_quarkus_cert_file: conf/cert.pem roles: diff --git a/playbooks/keycloak_realm.yml b/playbooks/keycloak_realm.yml index f03edab..99b2ef8 100644 --- a/playbooks/keycloak_realm.yml +++ b/playbooks/keycloak_realm.yml @@ -10,17 +10,17 @@ - TestClient1Admin - TestClient1User realm: TestRealm - public_client: True + public_client: true web_origins: - http://testclient1origin/application - http://testclient1origin/other users: - - username: TestUser - password: password - client_roles: - - client: TestClient1 - role: TestClient1User - realm: TestRealm + - username: TestUser + password: password + client_roles: + - client: TestClient1 + role: TestClient1User + realm: TestRealm roles: - role: middleware_automation.keycloak.keycloak_realm keycloak_realm: TestRealm diff --git a/playbooks/rhsso.yml b/playbooks/rhsso.yml index ea67158..ea61f66 100644 --- a/playbooks/rhsso.yml +++ b/playbooks/rhsso.yml @@ -3,6 +3,6 @@ hosts: sso vars: keycloak_admin_password: "remembertochangeme" - sso_enable: True + sso_enable: true roles: - middleware_automation.keycloak.keycloak diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index 17149f7..c4dfedc 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -39,7 +39,7 @@ Versions Patching -------- -When variable `keycloak_rhsso_apply_patches` is `True` (default: `False`), the role will automatically apply the latest cumulative patch for the selected base version. +When variable `keycloak_rhsso_apply_patches` is `true` (default: `false`), the role will automatically apply the latest cumulative patch for the selected base version. | RH-SSO VERSION | Release Date | RH-SSO LATEST CP | Notes | |:---------------|:------------------|:-----------------|:----------------| @@ -55,7 +55,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| |`keycloak_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` | -|`keycloak_ha_discovery`| Discovery protocol for HA cluster members | `JDBC_PING` if keycloak_db_enabled else `TCPPING` | +|`keycloak_ha_discovery`| Discovery protocol for HA cluster members | `JDBC_PING` if `keycloak_db_enabled` else `TCPPING` | |`keycloak_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_ha_enabled` is True, else `False` | |`keycloak_remote_cache_enabled`| Enable remote cache store when in clustered ha configurations | `True` if `keycloak_ha_enabled` else `False` | |`keycloak_admin_user`| Administration console user account | `admin` | @@ -68,19 +68,19 @@ Role Defaults |`keycloak_jgroups_port`| jgroups cluster tcp port | `7600` | |`keycloak_management_http_port`| Management port | `9990` | |`keycloak_management_https_port`| TLS management port | `9993` | -|`keycloak_prefer_ipv4`| Prefer IPv4 stack and addresses for port binding | `True` | +|`keycloak_prefer_ipv4`| Prefer IPv4 stack and addresses for port binding | `true` | |`keycloak_config_standalone_xml`| filename for configuration | `keycloak.xml` | |`keycloak_service_user`| posix account username | `keycloak` | |`keycloak_service_group`| posix account group | `keycloak` | -|`keycloak_service_restart_always`| systemd restart always behavior activation | `False` -|`keycloak_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` +|`keycloak_service_restart_always`| systemd restart always behavior activation | `False` | +|`keycloak_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` | |`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` | |`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` | |`keycloak_service_restartsec`| systemd RestartSec | `10s` | |`keycloak_service_pidfile`| pid file path for service | `/run/keycloak/keycloak.pid` | |`keycloak_features` | List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]` | `[]` |`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` | -|`keycloak_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path | `None` | +|`keycloak_java_home`| `JAVA_HOME` of installed JRE, leave empty for using RPM path at `keycloak_jvm_package` | `None` | |`keycloak_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | @@ -88,12 +88,12 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| -|`keycloak_offline_install` | perform an offline install | `False`| +|`keycloak_offline_install` | perform an offline install | `false`| |`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| |`keycloak_version`| keycloak.org package version | `18.0.2` | |`keycloak_dest`| Installation root path | `/opt/keycloak` | |`keycloak_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}` | -|`keycloak_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | +|`keycloak_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `false` | * Miscellaneous configuration @@ -110,13 +110,13 @@ Role Defaults |`keycloak_config_override_template` | Path to custom template for standalone.xml configuration | `''` | |`keycloak_auth_realm` | Name for rest authentication realm | `master` | |`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` | -|`keycloak_force_install` | Remove pre-existing versions of service | `False` | +|`keycloak_force_install` | Remove pre-existing versions of service | `false` | |`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}` | |`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}` | -|`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `False` | -|`keycloak_db_background_validation` | Enable background validation of database connection | `False` | +|`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `false` | +|`keycloak_db_background_validation` | Enable background validation of database connection | `false` | |`keycloak_db_background_validation_millis`| How frequenly the connection pool is validated in the background | `10000` if background validation enabled | -|`keycloak_db_background_validate_on_match` | Enable validate on match for database connections | `False` | +|`keycloak_db_background_validate_on_match` | Enable validate on match for database connections | `false` | |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | |`keycloak_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | @@ -132,7 +132,7 @@ The following are a set of _required_ variables for the role: |`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` | -The following parameters are _required_ only when `keycloak_ha_enabled` is True: +The following parameters are _required_ only when `keycloak_ha_enabled` is true: | Variable | Description | Default | |:---------|:------------|:--------| @@ -150,7 +150,7 @@ The following parameters are _required_ only when `keycloak_ha_enabled` is True: |`keycloak_infinispan_trust_store_password`| Password for opening truststore | `changeit` | -The following parameters are _required_ only when `keycloak_db_enabled` is True: +The following parameters are _required_ only when `keycloak_db_enabled` is true: | Variable | Description | Default | |:---------|:------------|:---------| @@ -196,7 +196,7 @@ Example Playbook name: keycloak vars: keycloak_admin_password: "remembertochangeme" - keycloak_offline_install: True + keycloak_offline_install: true # This should be the filename of keycloak archive on Ansible node: keycloak-16.1.0.zip ``` diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 2b5cc35..7ffaec6 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -5,7 +5,7 @@ keycloak_archive: "keycloak-legacy-{{ keycloak_version }}.zip" keycloak_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_download_url_9x: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}" keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" -keycloak_offline_install: False +keycloak_offline_install: false ### Install location and service settings keycloak_jvm_package: java-1.8.0-openjdk-headless @@ -26,13 +26,13 @@ keycloak_service_name: keycloak keycloak_service_desc: Keycloak keycloak_service_start_delay: 10 keycloak_service_start_retries: 25 -keycloak_service_restart_always: False -keycloak_service_restart_on_failure: False +keycloak_service_restart_always: false +keycloak_service_restart_on_failure: false keycloak_service_startlimitintervalsec: "300" keycloak_service_startlimitburst: "5" keycloak_service_restartsec: "10s" -keycloak_configure_firewalld: False +keycloak_configure_firewalld: false ### administrator console password keycloak_admin_password: '' @@ -49,11 +49,11 @@ keycloak_management_port_bind_address: 127.0.0.1 keycloak_management_http_port: 9990 keycloak_management_https_port: 9993 keycloak_java_opts: "-Xms1024m -Xmx2048m" -keycloak_prefer_ipv4: True +keycloak_prefer_ipv4: true keycloak_features: [] ### Enable configuration for database backend, clustering and remote caches on infinispan -keycloak_ha_enabled: False +keycloak_ha_enabled: false ### Enable database configuration, must be enabled when HA is configured keycloak_db_enabled: "{{ True if keycloak_ha_enabled else False }}" ### Discovery protocol for ha cluster members, valus [ 'JDBC_PING', 'TCPPING' ] @@ -66,7 +66,7 @@ keycloak_admin_user: admin keycloak_auth_realm: master keycloak_auth_client: admin-cli -keycloak_force_install: False +keycloak_force_install: false ### mod_cluster reverse proxy list keycloak_modcluster_enabled: "{{ True if keycloak_ha_enabled else False }}" @@ -78,7 +78,7 @@ keycloak_modcluster_urls: ### keycloak frontend url keycloak_frontend_url: http://localhost:8080/auth/ -keycloak_frontend_url_force: False +keycloak_frontend_url_force: false keycloak_admin_url: ### infinispan remote caches access (hotrod) @@ -86,7 +86,7 @@ keycloak_infinispan_user: supervisor keycloak_infinispan_pass: supervisor keycloak_infinispan_url: localhost keycloak_infinispan_sasl_mechanism: SCRAM-SHA-512 -keycloak_infinispan_use_ssl: False +keycloak_infinispan_use_ssl: false # if ssl is enabled, import ispn server certificate here keycloak_infinispan_trust_store_path: /etc/pki/java/cacerts keycloak_infinispan_trust_store_password: changeit @@ -97,9 +97,9 @@ keycloak_jdbc_engine: postgres keycloak_db_user: keycloak-user keycloak_db_pass: keycloak-pass ## connection validation -keycloak_db_background_validation: False +keycloak_db_background_validation: false keycloak_db_background_validation_millis: "{{ 10000 if keycloak_db_background_validation else 0 }}" -keycloak_db_background_validate_on_match: False +keycloak_db_background_validate_on_match: false keycloak_jdbc_url: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].url }}" keycloak_jdbc_driver_version: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].version }}" # override the variables above, following defaults show minimum supported versions @@ -114,7 +114,7 @@ keycloak_default_jdbc: url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;' version: 12.2.0 # role specific vars -keycloak_no_log: True +keycloak_no_log: true ### logging configuration keycloak_log_target: /var/log/keycloak diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 2e93667..acdb309 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -214,7 +214,7 @@ argument_specs: description: "Frontend URL for keycloak endpoints when a reverse proxy is used" type: "str" keycloak_frontend_url_force: - default: False + default: false description: "Force backend requests to use the frontend URL" type: "bool" keycloak_infinispan_user: @@ -337,7 +337,7 @@ argument_specs: description: "Enable remote cache store when in clustered ha configurations" type: "bool" keycloak_db_background_validation: - default: False + default: false description: "Enable background validation of database connection" type: "bool" keycloak_db_background_validation_millis: @@ -345,19 +345,19 @@ argument_specs: description: "How frequenly the connection pool is validated in the background" type: 'int' keycloak_db_background_validate_on_match: - default: False + default: false description: "Enable validate on match for database connections" type: "bool" keycloak_db_valid_conn_sql: - required: False + required: false description: "Override the default database connection validation query sql" type: "str" keycloak_admin_url: - required: False + required: false description: "Override the default administration endpoint URL" type: "str" keycloak_jgroups_subnet: - required: False + required: false description: "Override the subnet match for jgroups cluster formation; if not defined, it will be inferred from local machine route configuration" type: "str" keycloak_log_target: @@ -383,15 +383,15 @@ argument_specs: description: "Installation path for Red Hat SSO" type: "str" sso_apply_patches: - default: False + default: false description: "Install Red Hat SSO most recent cumulative patch" type: "bool" sso_enable: - default: True + default: true description: "Enable Red Hat Single Sign-on installation" type: "str" sso_offline_install: - default: False + default: false description: "Perform an offline install" type: "bool" sso_service_name: @@ -403,7 +403,7 @@ argument_specs: description: "systemd description for Red Hat Single Sign-On" type: "str" sso_patch_version: - required: False + required: false description: "Red Hat Single Sign-On latest cumulative patch version to apply; defaults to latest version when sso_apply_patches is True" type: "str" sso_patch_bundle: diff --git a/roles/keycloak/meta/main.yml b/roles/keycloak/meta/main.yml index 5a121ba..a70e9f1 100644 --- a/roles/keycloak/meta/main.yml +++ b/roles/keycloak/meta/main.yml @@ -15,9 +15,9 @@ galaxy_info: min_ansible_version: "2.14" platforms: - - name: EL - versions: - - "8" + - name: EL + versions: + - "8" galaxy_tags: - keycloak diff --git a/roles/keycloak/tasks/fastpackages.yml b/roles/keycloak/tasks/fastpackages.yml index cfd9025..c9085f8 100644 --- a/roles/keycloak/tasks/fastpackages.yml +++ b/roles/keycloak/tasks/fastpackages.yml @@ -2,15 +2,15 @@ - name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" register: rpm_info - changed_when: False - failed_when: False + changed_when: false + failed_when: false - name: "Add missing packages to the yum install list" ansible.builtin.set_fact: packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" - name: "Install packages: {{ packages_to_install }}" - become: True + become: true ansible.builtin.yum: name: "{{ packages_to_install }}" state: present diff --git a/roles/keycloak/tasks/firewalld.yml b/roles/keycloak/tasks/firewalld.yml index 0cf4ee3..f48f580 100644 --- a/roles/keycloak/tasks/firewalld.yml +++ b/roles/keycloak/tasks/firewalld.yml @@ -6,19 +6,19 @@ - firewalld - name: Enable and start the firewalld service - become: yes + become: true ansible.builtin.systemd: name: firewalld - enabled: yes + enabled: true state: started -- name: "Configure firewall for {{ keycloak.service_name }} ports" - become: yes +- name: "Configure firewall ports for {{ keycloak.service_name }}" + become: true ansible.posix.firewalld: port: "{{ item }}" permanent: true state: enabled - immediate: yes + immediate: true loop: - "{{ keycloak_http_port }}/tcp" - "{{ keycloak_https_port }}/tcp" diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index a2467d3..67b98cd 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -11,7 +11,7 @@ quiet: true - name: Check for an existing deployment - become: yes + become: true ansible.builtin.stat: path: "{{ keycloak_jboss_home }}" register: existing_deploy @@ -20,32 +20,32 @@ when: existing_deploy.stat.exists and keycloak_force_install | bool block: - name: "Stop the old {{ keycloak.service_name }} service" - become: yes - ignore_errors: yes + become: true + failed_when: false ansible.builtin.systemd: name: keycloak state: stopped - name: "Remove the old {{ keycloak.service_name }} deployment" - become: yes + become: true ansible.builtin.file: path: "{{ keycloak_jboss_home }}" state: absent - name: Check for an existing deployment after possible forced removal - become: yes + become: true ansible.builtin.stat: path: "{{ keycloak_jboss_home }}" -- name: "Create {{ keycloak.service_name }} service user/group" - become: yes +- name: "Create service user/group for {{ keycloak.service_name }}" + become: true ansible.builtin.user: name: "{{ keycloak_service_user }}" home: /opt/keycloak system: yes create_home: no -- name: "Create {{ keycloak.service_name }} install location" - become: yes +- name: "Create install location for {{ keycloak.service_name }}" + become: true ansible.builtin.file: dest: "{{ keycloak_dest }}" state: directory @@ -54,7 +54,7 @@ mode: 0750 - name: Create pidfile folder - become: yes + become: true ansible.builtin.file: dest: "{{ keycloak_service_pidfile | dirname }}" state: directory @@ -68,7 +68,7 @@ archive: "{{ keycloak_dest }}/{{ keycloak.bundle }}" - name: Check download archive path - become: yes + become: true ansible.builtin.stat: path: "{{ archive }}" register: archive_path @@ -86,7 +86,7 @@ dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" mode: 0644 delegate_to: localhost - run_once: yes + run_once: true when: - archive_path is defined - archive_path.stat is defined @@ -96,7 +96,7 @@ - name: Perform download from RHN using JBoss Network API delegate_to: localhost - run_once: yes + run_once: true when: - archive_path is defined - archive_path.stat is defined @@ -114,13 +114,13 @@ register: rhn_products no_log: "{{ omit_rhn_output | default(true) }}" delegate_to: localhost - run_once: yes + run_once: true - name: Determine install zipfile from search results ansible.builtin.set_fact: rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/' + sso_archive + '$') }}" delegate_to: localhost - run_once: yes + run_once: true - name: Download Red Hat Single Sign-On middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user @@ -130,7 +130,7 @@ dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" no_log: "{{ omit_rhn_output | default(true) }}" delegate_to: localhost - run_once: yes + run_once: true - name: Download rhsso archive from alternate location ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user @@ -138,7 +138,7 @@ dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" mode: 0644 delegate_to: localhost - run_once: yes + run_once: true when: - archive_path is defined - archive_path.stat is defined @@ -166,23 +166,23 @@ - not archive_path.stat.exists - local_archive_path.stat is defined - local_archive_path.stat.exists - become: yes + become: true - name: "Check target directory: {{ keycloak.home }}" ansible.builtin.stat: path: "{{ keycloak.home }}" register: path_to_workdir - become: yes + become: true - name: "Extract {{ keycloak_service_desc }} archive on target" ansible.builtin.unarchive: - remote_src: yes + remote_src: true src: "{{ archive }}" dest: "{{ keycloak_dest }}" creates: "{{ keycloak.home }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" - become: yes + become: true when: - new_version_downloaded.changed or not path_to_workdir.stat.exists notify: @@ -200,13 +200,13 @@ owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" recurse: true - become: yes + become: true changed_when: false - name: Ensure permissions are correct on existing deploy ansible.builtin.command: chown -R "{{ keycloak_service_user }}:{{ keycloak_service_group }}" "{{ keycloak.home }}" when: keycloak_service_runas - become: yes + become: true changed_when: false # driver and configuration @@ -215,7 +215,7 @@ when: keycloak_jdbc[keycloak_jdbc_engine].enabled - name: "Deploy custom {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak_config_override_template }}" - become: yes + become: true ansible.builtin.template: src: "templates/{{ keycloak_config_override_template }}" dest: "{{ keycloak_config_path_to_standalone_xml }}" @@ -227,7 +227,7 @@ when: keycloak_config_override_template | length > 0 - name: "Deploy standalone {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}" - become: yes + become: true ansible.builtin.template: src: templates/standalone.xml.j2 dest: "{{ keycloak_config_path_to_standalone_xml }}" @@ -255,7 +255,7 @@ when: keycloak_ha_enabled and keycloak_ha_discovery == 'TCPPING' - name: "Deploy HA {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}" - become: yes + become: true ansible.builtin.template: src: templates/standalone-ha.xml.j2 dest: "{{ keycloak_config_path_to_standalone_xml }}" @@ -270,7 +270,7 @@ - keycloak_config_override_template | length == 0 - name: "Deploy HA {{ keycloak.service_name }} config with infinispan remote cache store to {{ keycloak_config_path_to_standalone_xml }}" - become: yes + become: true ansible.builtin.template: src: templates/standalone-infinispan.xml.j2 dest: "{{ keycloak_config_path_to_standalone_xml }}" @@ -285,7 +285,7 @@ - keycloak_config_override_template | length == 0 - name: "Deploy profile.properties file to {{ keycloak_config_path_to_properties }}" - become: yes + become: true ansible.builtin.template: src: keycloak-profile.properties.j2 dest: "{{ keycloak_config_path_to_properties }}" diff --git a/roles/keycloak/tasks/jdbc_driver.yml b/roles/keycloak/tasks/jdbc_driver.yml index 7dfaabc..1b0a1ec 100644 --- a/roles/keycloak/tasks/jdbc_driver.yml +++ b/roles/keycloak/tasks/jdbc_driver.yml @@ -3,17 +3,17 @@ ansible.builtin.stat: path: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}" register: dest_path - become: yes + become: true - name: "Set up module dir for JDBC Driver {{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}" ansible.builtin.file: path: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}" state: directory - recurse: yes + recurse: true owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" mode: 0750 - become: yes + become: true when: - not dest_path.stat.exists @@ -24,7 +24,7 @@ group: "{{ keycloak_service_group }}" owner: "{{ keycloak_service_user }}" mode: 0640 - become: yes + become: true - name: "Deploy module.xml for JDBC Driver" ansible.builtin.template: @@ -33,4 +33,4 @@ group: "{{ keycloak_service_group }}" owner: "{{ keycloak_service_user }}" mode: 0640 - become: yes + become: true diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index 7fe0222..cba503b 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -35,7 +35,7 @@ state: link src: "{{ keycloak_jboss_home }}/standalone/log" dest: "{{ keycloak_log_target }}" - become: yes + become: true - name: Set admin credentials and restart if not already created block: @@ -44,7 +44,7 @@ url: "{{ keycloak_url }}/auth/realms/master/protocol/openid-connect/token" method: POST body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password" - validate_certs: no + validate_certs: false register: keycloak_auth_response until: keycloak_auth_response.status == 200 retries: 2 @@ -58,8 +58,8 @@ - "-rmaster" - "-u{{ keycloak_admin_user }}" - "-p{{ keycloak_admin_password }}" - changed_when: yes - become: yes + changed_when: true + become: true - name: "Restart {{ keycloak.service_name }}" ansible.builtin.include_tasks: tasks/restart_keycloak.yml - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index 02370c7..aad814b 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -3,7 +3,7 @@ ansible.builtin.assert: that: - keycloak_admin_password | length > 12 - quiet: True + quiet: true fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_admin_password variable to a 12+ char long string" success_msg: "{{ 'Console administrator password OK' }}" @@ -11,7 +11,7 @@ ansible.builtin.assert: that: - (keycloak_ha_enabled and keycloak_db_enabled) or (not keycloak_ha_enabled and keycloak_db_enabled) or (not keycloak_ha_enabled and not keycloak_db_enabled) - quiet: True + quiet: true fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_ha_enabled and keycloak_db_enabled" success_msg: "{{ 'Configuring HA' if keycloak_ha_enabled else 'Configuring standalone' }}" @@ -20,7 +20,7 @@ that: - (rhn_username is defined and sso_enable is defined and sso_enable) or not sso_enable is defined or not sso_enable or keycloak_offline_install - (rhn_password is defined and sso_enable is defined and sso_enable) or not sso_enable is defined or not sso_enable or keycloak_offline_install - quiet: True + quiet: true fail_msg: "Cannot install Red Hat SSO without RHN credentials. Check rhn_username and rhn_password are defined" success_msg: "Installing {{ keycloak_service_desc }}" @@ -31,7 +31,7 @@ - keycloak_jdbc_url | length > 0 - keycloak_db_user | length > 0 - keycloak_db_pass | length > 0 - quiet: True + quiet: true fail_msg: "Configuration for the JDBC persistence is invalid or incomplete" success_msg: "Configuring JDBC persistence using {{ keycloak_jdbc_engine }} database" when: keycloak_db_enabled diff --git a/roles/keycloak/tasks/restart_keycloak.yml b/roles/keycloak/tasks/restart_keycloak.yml index a0ae41f..bae91cd 100644 --- a/roles/keycloak/tasks/restart_keycloak.yml +++ b/roles/keycloak/tasks/restart_keycloak.yml @@ -2,11 +2,12 @@ - name: "Restart and enable {{ keycloak.service_name }} service" ansible.builtin.systemd: name: keycloak - enabled: yes + enabled: true state: restarted - become: yes + daemon_reload: true + become: true delegate_to: "{{ ansible_play_hosts | first }}" - run_once: True + run_once: true - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" ansible.builtin.uri: @@ -14,7 +15,7 @@ register: keycloak_status until: keycloak_status.status == 200 delegate_to: "{{ ansible_play_hosts | first }}" - run_once: True + run_once: true retries: "{{ keycloak_service_start_retries }}" delay: "{{ keycloak_service_start_delay }}" @@ -23,5 +24,5 @@ name: keycloak enabled: yes state: restarted - become: yes + become: true when: inventory_hostname != ansible_play_hosts | first diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index b03b55c..b0e04da 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -12,11 +12,11 @@ path: "{{ patch_archive }}" register: patch_archive_path when: sso_patch_version is defined - become: yes + become: true - name: Perform patch download from RHN via JBossNetwork API delegate_to: localhost - run_once: yes + run_once: true when: - sso_enable is defined and sso_enable - not keycloak_offline_install @@ -32,21 +32,21 @@ register: rhn_products no_log: "{{ omit_rhn_output | default(true) }}" delegate_to: localhost - run_once: yes + run_once: true - name: Determine patch versions list ansible.builtin.set_fact: - filtered_versions: "{{ rhn_products.results | map(attribute='file_path') | select('match', '^[^/]*/rh-sso-.*[0-9]*[.][0-9]*[.][0-9]*.*$') | map('regex_replace','[^/]*/rh-sso-([0-9]*[.][0-9]*[.][0-9]*)-.*','\\1' ) | list | unique }}" + filtered_versions: "{{ rhn_products.results | map(attribute='file_path') | select('match', '^[^/]*/rh-sso-.*[0-9]*[.][0-9]*[.][0-9]*.*$') | map('regex_replace', '[^/]*/rh-sso-([0-9]*[.][0-9]*[.][0-9]*)-.*', '\\1') | list | unique }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 delegate_to: localhost - run_once: yes + run_once: true - name: Determine latest version ansible.builtin.set_fact: sso_latest_version: "{{ filtered_versions | middleware_automation.common.version_sort | last }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 delegate_to: localhost - run_once: yes + run_once: true - name: Determine install zipfile from search results ansible.builtin.set_fact: @@ -55,7 +55,7 @@ patch_version: "{{ sso_latest_version }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 delegate_to: localhost - run_once: yes + run_once: true - name: "Determine selected patch from supplied version: {{ sso_patch_version }}" ansible.builtin.set_fact: @@ -64,7 +64,7 @@ patch_version: "{{ sso_patch_version }}" when: sso_patch_version is defined delegate_to: localhost - run_once: yes + run_once: true - name: Download Red Hat Single Sign-On patch middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user @@ -74,7 +74,7 @@ dest: "{{ local_path.stat.path }}/{{ patch_bundle }}" no_log: "{{ omit_rhn_output | default(true) }}" delegate_to: localhost - run_once: yes + run_once: true - name: Set download patch archive path ansible.builtin.set_fact: @@ -84,7 +84,7 @@ ansible.builtin.stat: path: "{{ patch_archive }}" register: patch_archive_path - become: yes + become: true ## copy and unpack - name: Copy patch archive to target nodes @@ -99,7 +99,7 @@ - not patch_archive_path.stat.exists - local_archive_path.stat is defined - local_archive_path.stat.exists - become: yes + become: true - name: "Check installed patches" ansible.builtin.include_tasks: rhsso_cli.yml @@ -107,7 +107,7 @@ query: "patch info" args: apply: - become: yes + become: true become_user: "{{ keycloak_service_user }}" - name: "Perform patching" @@ -122,7 +122,7 @@ query: "patch apply {{ patch_archive }}" args: apply: - become: yes + become: true become_user: "{{ keycloak_service_user }}" - name: "Restart server to ensure patch content is running" @@ -133,7 +133,7 @@ - cli_result.rc == 0 args: apply: - become: yes + become: true become_user: "{{ keycloak_service_user }}" - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" @@ -150,7 +150,7 @@ query: "patch info" args: apply: - become: yes + become: true become_user: "{{ keycloak_service_user }}" - name: "Verify installed patch version" diff --git a/roles/keycloak/tasks/start_keycloak.yml b/roles/keycloak/tasks/start_keycloak.yml index 524df80..5aed248 100644 --- a/roles/keycloak/tasks/start_keycloak.yml +++ b/roles/keycloak/tasks/start_keycloak.yml @@ -2,9 +2,10 @@ - name: "Start {{ keycloak.service_name }} service" ansible.builtin.systemd: name: keycloak - enabled: yes + enabled: true state: started - become: yes + daemon_reload: true + become: true - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" ansible.builtin.uri: diff --git a/roles/keycloak/tasks/stop_keycloak.yml b/roles/keycloak/tasks/stop_keycloak.yml index fd87802..7f30433 100644 --- a/roles/keycloak/tasks/stop_keycloak.yml +++ b/roles/keycloak/tasks/stop_keycloak.yml @@ -2,6 +2,6 @@ - name: "Stop {{ keycloak.service_name }}" ansible.builtin.systemd: name: keycloak - enabled: yes + enabled: true state: stopped - become: yes + become: true diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index 4b24822..cd58345 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -1,6 +1,6 @@ --- - name: "Configure {{ keycloak.service_name }} service script wrapper" - become: yes + become: true ansible.builtin.template: src: keycloak-service.sh.j2 dest: "{{ keycloak_dest }}/keycloak-service.sh" @@ -15,7 +15,7 @@ rpm_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" - name: "Configure sysconfig file for {{ keycloak.service_name }} service" - become: yes + become: true ansible.builtin.template: src: keycloak-sysconfig.j2 dest: /etc/sysconfig/keycloak @@ -34,20 +34,14 @@ owner: root group: root mode: 0644 - become: yes + become: true register: systemdunit notify: - restart keycloak -- name: Reload systemd - become: yes - ansible.builtin.systemd: - daemon_reload: yes - when: systemdunit.changed - - name: "Start and wait for {{ keycloak.service_name }} service (first node db)" ansible.builtin.include_tasks: start_keycloak.yml - run_once: yes + run_once: true when: keycloak_db_enabled - name: "Start and wait for {{ keycloak.service_name }} service (remaining nodes)" @@ -56,7 +50,7 @@ - name: Check service status ansible.builtin.command: "systemctl status keycloak" register: keycloak_service_status - changed_when: False + changed_when: false - name: Verify service status ansible.builtin.assert: diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 51ca792..adf918d 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -6,7 +6,7 @@ keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/do keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" # whether to install from local archive -keycloak_quarkus_offline_install: False +keycloak_quarkus_offline_install: false ### Install location and service settings keycloak_quarkus_jvm_package: java-17-openjdk-headless @@ -14,11 +14,11 @@ keycloak_quarkus_java_home: keycloak_quarkus_dest: /opt/keycloak keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" keycloak_quarkus_config_dir: "{{ keycloak_quarkus_home }}/conf" -keycloak_quarkus_start_dev: False +keycloak_quarkus_start_dev: false keycloak_quarkus_service_user: keycloak keycloak_quarkus_service_group: keycloak keycloak_quarkus_service_pidfile: "/run/keycloak/keycloak.pid" -keycloak_quarkus_configure_firewalld: False +keycloak_quarkus_configure_firewalld: false ### administrator console password keycloak_quarkus_admin_user: admin @@ -30,7 +30,7 @@ keycloak_quarkus_bind_address: 0.0.0.0 keycloak_quarkus_host: localhost keycloak_quarkus_port: -1 keycloak_quarkus_path: -keycloak_quarkus_http_enabled: True +keycloak_quarkus_http_enabled: true keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 keycloak_quarkus_ajp_port: 8009 @@ -38,20 +38,20 @@ keycloak_quarkus_jgroups_port: 7600 keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m" ### TLS/HTTPS configuration -keycloak_quarkus_https_key_file_enabled: False +keycloak_quarkus_https_key_file_enabled: false keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/server.key.pem" keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/server.crt.pem" #### key store configuration -keycloak_quarkus_https_key_store_enabled: False +keycloak_quarkus_https_key_store_enabled: false keycloak_quarkus_key_store_file: "{{ keycloak.home }}/conf/key_store.p12" keycloak_quarkus_key_store_password: '' ##### trust store configuration -keycloak_quarkus_https_trust_store_enabled: False +keycloak_quarkus_https_trust_store_enabled: false keycloak_quarkus_trust_store_file: "{{ keycloak.home }}/conf/trust_store.p12" keycloak_quarkus_trust_store_password: '' ### Enable configuration for database backend, clustering and remote caches on infinispan -keycloak_quarkus_ha_enabled: False +keycloak_quarkus_ha_enabled: false ### Enable database configuration, must be enabled when HA is configured keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False }}" @@ -67,17 +67,17 @@ keycloak_quarkus_http_relative_path: / keycloak_quarkus_proxy_mode: edge # disable xa transactions -keycloak_quarkus_transaction_xa_enabled: True +keycloak_quarkus_transaction_xa_enabled: true -keycloak_quarkus_metrics_enabled: False -keycloak_quarkus_health_enabled: True +keycloak_quarkus_metrics_enabled: false +keycloak_quarkus_health_enabled: true ### infinispan remote caches access (hotrod) keycloak_quarkus_ispn_user: supervisor keycloak_quarkus_ispn_pass: supervisor keycloak_quarkus_ispn_url: localhost keycloak_quarkus_ispn_sasl_mechanism: SCRAM-SHA-512 -keycloak_quarkus_ispn_use_ssl: False +keycloak_quarkus_ispn_use_ssl: false # if ssl is enabled, import ispn server certificate here keycloak_quarkus_ispn_trust_store_path: /etc/pki/java/cacerts keycloak_quarkus_ispn_trust_store_password: changeit diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index d260910..89163aa 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -138,12 +138,12 @@ argument_specs: type: "bool" keycloak_quarkus_trust_store_file: default: "{{ keycloak.home }}/conf/trust_store.p12" - description: "The file pat to the trust store" + description: "The file path to the trust store" type: "str" keycloak_quarkus_trust_store_password: - default: "" - description: "Password for the trust store" - type: "str" + default: "" + description: "Password for the trust store" + type: "str" keycloak_quarkus_https_port: # line 30 of defaults/main.yml default: 8443 @@ -281,10 +281,10 @@ argument_specs: type: "str" description: "The proxy address forwarding mode if the server is behind a reverse proxy. Set to 'none' if not using a proxy" keycloak_quarkus_start_dev: - default: False + default: false type: "bool" description: "Whether to start the service in development mode (start-dev)" keycloak_quarkus_transaction_xa_enabled: - default: True + default: true type: "bool" description: "Enable or disable XA transactions which may not be supported by some DBMS" diff --git a/roles/keycloak_quarkus/meta/main.yml b/roles/keycloak_quarkus/meta/main.yml index 2a6acf8..469a71d 100644 --- a/roles/keycloak_quarkus/meta/main.yml +++ b/roles/keycloak_quarkus/meta/main.yml @@ -11,9 +11,9 @@ galaxy_info: min_ansible_version: "2.14" platforms: - - name: EL - versions: - - "8" + - name: EL + versions: + - "8" galaxy_tags: - keycloak diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml index cfd9025..c9085f8 100644 --- a/roles/keycloak_quarkus/tasks/fastpackages.yml +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -2,15 +2,15 @@ - name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}" register: rpm_info - changed_when: False - failed_when: False + changed_when: false + failed_when: false - name: "Add missing packages to the yum install list" ansible.builtin.set_fact: packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" - name: "Install packages: {{ packages_to_install }}" - become: True + become: true ansible.builtin.yum: name: "{{ packages_to_install }}" state: present diff --git a/roles/keycloak_quarkus/tasks/firewalld.yml b/roles/keycloak_quarkus/tasks/firewalld.yml index 6c81021..2c3ef74 100644 --- a/roles/keycloak_quarkus/tasks/firewalld.yml +++ b/roles/keycloak_quarkus/tasks/firewalld.yml @@ -6,19 +6,19 @@ - firewalld - name: Enable and start the firewalld service - become: yes + become: true ansible.builtin.systemd: name: firewalld - enabled: yes + enabled: true state: started - name: "Configure firewall for {{ keycloak.service_name }} ports" - become: yes + become: true ansible.posix.firewalld: port: "{{ item }}" permanent: true state: enabled - immediate: yes + immediate: true loop: - "{{ keycloak_quarkus_http_port }}/tcp" - "{{ keycloak_quarkus_https_port }}/tcp" diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index b1ea1ee..887aa31 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -11,21 +11,21 @@ quiet: true - name: Check for an existing deployment - become: yes + become: true ansible.builtin.stat: path: "{{ keycloak.home }}" register: existing_deploy - name: "Create {{ keycloak.service_name }} service user/group" - become: yes + become: true ansible.builtin.user: name: "{{ keycloak.service_user }}" home: /opt/keycloak - system: yes + system: true create_home: no - name: "Create {{ keycloak.service_name }} install location" - become: yes + become: true ansible.builtin.file: dest: "{{ keycloak_quarkus_dest }}" state: directory @@ -39,7 +39,7 @@ archive: "{{ keycloak_quarkus_dest }}/{{ keycloak.bundle }}" - name: Check download archive path - become: yes + become: true ansible.builtin.stat: path: "{{ archive }}" register: archive_path @@ -82,23 +82,23 @@ - not archive_path.stat.exists - local_archive_path.stat is defined - local_archive_path.stat.exists - become: yes + become: true - name: "Check target directory: {{ keycloak.home }}/bin/" ansible.builtin.stat: path: "{{ keycloak.home }}/bin/" register: path_to_workdir - become: yes + become: true - name: "Extract Keycloak archive on target" ansible.builtin.unarchive: - remote_src: yes + remote_src: true src: "{{ archive }}" dest: "{{ keycloak_quarkus_dest }}" creates: "{{ keycloak.home }}/bin/" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - become: yes + become: true when: - (not path_to_workdir.stat.exists) or new_version_downloaded.changed notify: diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 43cbb38..93a68c0 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -28,7 +28,7 @@ owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: 0644 - become: yes + become: true notify: - restart keycloak @@ -39,7 +39,7 @@ owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: 0644 - become: yes + become: true notify: - restart keycloak @@ -50,7 +50,7 @@ owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: 0775 - become: yes + become: true - name: Flush pending handlers ansible.builtin.meta: flush_handlers @@ -61,12 +61,12 @@ - name: Check service status ansible.builtin.command: "systemctl status keycloak" register: keycloak_service_status - changed_when: False + changed_when: false - name: Link default logs directory ansible.builtin.file: state: link src: "{{ keycloak.log.file | dirname }}" dest: "{{ keycloak_quarkus_log_target }}" - force: yes - become: yes + force: true + become: true diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index be807df..ee2abca 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -3,7 +3,7 @@ ansible.builtin.assert: that: - keycloak_quarkus_admin_pass | length > 12 - quiet: True + quiet: true fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass variable to a 12+ char long string" success_msg: "{{ 'Console administrator password OK' }}" @@ -11,7 +11,7 @@ ansible.builtin.assert: that: - keycloak_quarkus_http_relative_path is regex('^/.*') - quiet: True + quiet: true fail_msg: "the relative path must begin with /" success_msg: "{{ 'relative path OK' }}" @@ -19,7 +19,7 @@ ansible.builtin.assert: that: - (keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and not keycloak_quarkus_db_enabled) - quiet: True + quiet: true fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled" success_msg: "{{ 'Configuring HA' if keycloak_quarkus_ha_enabled else 'Configuring standalone' }}" diff --git a/roles/keycloak_quarkus/tasks/restart.yml b/roles/keycloak_quarkus/tasks/restart.yml index eff9ddf..f709f75 100644 --- a/roles/keycloak_quarkus/tasks/restart.yml +++ b/roles/keycloak_quarkus/tasks/restart.yml @@ -2,6 +2,7 @@ - name: "Restart and enable {{ keycloak.service_name }} service" ansible.builtin.systemd: name: keycloak - enabled: yes + enabled: true state: restarted - become: yes + daemon_reload: true + become: true diff --git a/roles/keycloak_quarkus/tasks/start.yml b/roles/keycloak_quarkus/tasks/start.yml index bdf42f9..7ccc1b9 100644 --- a/roles/keycloak_quarkus/tasks/start.yml +++ b/roles/keycloak_quarkus/tasks/start.yml @@ -2,9 +2,10 @@ - name: "Start {{ keycloak.service_name }} service" ansible.builtin.systemd: name: keycloak - enabled: yes + enabled: true state: started - become: yes + daemon_reload: true + become: true - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" ansible.builtin.uri: diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index c0be72b..3d59b3f 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -4,7 +4,7 @@ rpm_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" - name: "Configure sysconfig file for keycloak service" - become: yes + become: true ansible.builtin.template: src: keycloak-sysconfig.j2 dest: /etc/sysconfig/keycloak @@ -23,13 +23,7 @@ owner: root group: root mode: 0644 - become: yes + become: true register: systemdunit notify: - restart keycloak - -- name: Reload systemd - become: yes - ansible.builtin.systemd: - daemon_reload: yes - when: systemdunit.changed diff --git a/roles/keycloak_realm/defaults/main.yml b/roles/keycloak_realm/defaults/main.yml index 17112d5..c396481 100644 --- a/roles/keycloak_realm/defaults/main.yml +++ b/roles/keycloak_realm/defaults/main.yml @@ -40,7 +40,7 @@ keycloak_clients: [] keycloak_client_default_roles: [] # if True, create a public client; otherwise, a confidetial client -keycloak_client_public: True +keycloak_client_public: true # allowed web origins for the client keycloak_client_web_origins: '+' diff --git a/roles/keycloak_realm/meta/argument_specs.yml b/roles/keycloak_realm/meta/argument_specs.yml index da3eca1..bc606ba 100644 --- a/roles/keycloak_realm/meta/argument_specs.yml +++ b/roles/keycloak_realm/meta/argument_specs.yml @@ -94,7 +94,7 @@ argument_specs: downstream: options: sso_version: - default: "7.5.0" + default: "7.6.0" description: "Red Hat Single Sign-On version" type: "str" sso_dest: @@ -106,10 +106,10 @@ argument_specs: description: "Installation path for Red Hat SSO" type: "str" sso_apply_patches: - default: False + default: false description: "Install Red Hat SSO most recent cumulative patch" type: "bool" sso_enable: - default: True + default: true description: "Enable Red Hat Single Sign-on installation" type: "str" diff --git a/roles/keycloak_realm/meta/main.yml b/roles/keycloak_realm/meta/main.yml index 8dfefcd..915f62c 100644 --- a/roles/keycloak_realm/meta/main.yml +++ b/roles/keycloak_realm/meta/main.yml @@ -11,9 +11,9 @@ galaxy_info: min_ansible_version: "2.14" platforms: - - name: EL - versions: - - "8" + - name: EL + versions: + - "8" galaxy_tags: - keycloak diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index c137270..c1f66bc 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -4,7 +4,7 @@ url: "{{ keycloak_url }}{{ keycloak_context }}/realms/master/protocol/openid-connect/token" method: POST body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password" - validate_certs: no + validate_certs: false no_log: "{{ keycloak_no_log | default('True') }}" register: keycloak_auth_response until: keycloak_auth_response.status == 200 @@ -28,7 +28,7 @@ url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms" method: POST body: "{{ lookup('template', 'realm.json.j2') }}" - validate_certs: no + validate_certs: false body_format: json headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" @@ -59,7 +59,7 @@ - item.name is defined and item.name | length > 0 - (item.client_id is defined and item.client_id | length > 0) or (item.id is defined and item.id | length > 0) fail_msg: "For each keycloak client, attributes `name` and either `id` or `client_id` is required" - quiet: True + quiet: true loop: "{{ keycloak_clients | flatten }}" loop_control: label: "{{ item.name | default('unnamed client') }}" diff --git a/roles/keycloak_realm/tasks/manage_user.yml b/roles/keycloak_realm/tasks/manage_user.yml index 840c738..1f9f7bd 100644 --- a/roles/keycloak_realm/tasks/manage_user.yml +++ b/roles/keycloak_realm/tasks/manage_user.yml @@ -2,7 +2,7 @@ - name: "Check if User Already Exists" ansible.builtin.uri: url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" - validate_certs: no + validate_certs: false headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" register: keycloak_user_search_result @@ -18,7 +18,7 @@ email: "{{ user.email | default(omit) }}" firstName: "{{ user.firstName | default(omit) }}" lastName: "{{ user.lastName | default(omit) }}" - validate_certs: no + validate_certs: false body_format: json headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" @@ -28,7 +28,7 @@ - name: "Get User" ansible.builtin.uri: url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" - validate_certs: no + validate_certs: false headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" register: keycloak_user @@ -41,7 +41,7 @@ type: password temporary: false value: "{{ user.password }}" - validate_certs: no + validate_certs: false body_format: json status_code: - 200 diff --git a/roles/keycloak_realm/tasks/manage_user_client_roles.yml b/roles/keycloak_realm/tasks/manage_user_client_roles.yml index 5369094..85de09a 100644 --- a/roles/keycloak_realm/tasks/manage_user_client_roles.yml +++ b/roles/keycloak_realm/tasks/manage_user_client_roles.yml @@ -31,7 +31,7 @@ containerId: "{{ item.containerId }}" name: "{{ item.name }}" composite: "{{ item.composite }}" - validate_certs: False + validate_certs: false body_format: json headers: Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" diff --git a/roles/keycloak_realm/tasks/manage_user_roles.yml b/roles/keycloak_realm/tasks/manage_user_roles.yml index ff803a2..dc74477 100644 --- a/roles/keycloak_realm/tasks/manage_user_roles.yml +++ b/roles/keycloak_realm/tasks/manage_user_roles.yml @@ -3,7 +3,7 @@ ansible.builtin.uri: url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" headers: - validate_certs: no + validate_certs: false Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" register: keycloak_user @@ -12,7 +12,7 @@ url: "{{ keycloak_url }}{{ keycloak_context }}/realms/master/protocol/openid-connect/token" method: POST body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password" - validate_certs: no + validate_certs: false register: keycloak_auth_response no_log: "{{ keycloak_no_log | default('True') }}" until: keycloak_auth_response.status == 200 diff --git a/roles/keycloak_realm/vars/main.yml b/roles/keycloak_realm/vars/main.yml index cbb9435..7664f8c 100644 --- a/roles/keycloak_realm/vars/main.yml +++ b/roles/keycloak_realm/vars/main.yml @@ -5,5 +5,5 @@ keycloak_realm: # other settings -keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + ( keycloak_jboss_port_offset | default(0) ) }}" -keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + ( keycloak_jboss_port_offset | default(0) ) }}" +keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + (keycloak_jboss_port_offset | default(0)) }}" +keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + (keycloak_jboss_port_offset | default(0)) }}" From 94530640c1d62c2fd58b45dd69b7471606664cd4 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 1 Dec 2023 12:37:20 +0100 Subject: [PATCH 127/376] update wf --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e5a542..d8905f0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: push: branches: - main - pull_request: + pull_request_target: schedule: - cron: '0 6 * * *' From 842e61c43ed506aecc686ddd327ede804850aa45 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 5 Dec 2023 10:13:12 +0100 Subject: [PATCH 128/376] Update template to lowercase booleans --- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index bc563ed..ac2defe 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -9,11 +9,11 @@ db-password={{ keycloak_quarkus_db_pass }} {% endif %} # Observability -metrics-enabled={{ keycloak_quarkus_metrics_enabled }} -health-enabled={{ keycloak_quarkus_health_enabled }} +metrics-enabled={{ keycloak_quarkus_metrics_enabled | lower }} +health-enabled={{ keycloak_quarkus_health_enabled | lower }} # HTTP -http-enabled={{ keycloak_quarkus_http_enabled }} +http-enabled={{ keycloak_quarkus_http_enabled | lower }} http-port={{ keycloak_quarkus_http_port }} http-relative-path={{ keycloak_quarkus_http_relative_path }} @@ -57,7 +57,7 @@ proxy={{ keycloak_quarkus_proxy_mode }} #spi-sticky-session-encoder-infinispan-should-attach-route=false # Transaction -transaction-xa-enabled={{ keycloak_quarkus_transaction_xa_enabled }} +transaction-xa-enabled={{ keycloak_quarkus_transaction_xa_enabled | lower }} # Logging #log-format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n From 72ca9f5dfa528c31ba46ae0ff6e657a14be8ee60 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 5 Dec 2023 10:26:20 +0100 Subject: [PATCH 129/376] switch pull_req_target to pull_req --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8905f0..6552ce1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,9 +4,9 @@ on: push: branches: - main - pull_request_target: + pull_request: schedule: - - cron: '0 6 * * *' + - cron: '15 6 * * *' jobs: ci: @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "quarkus", "overridexml", "quarkus-devmode", "https_revproxy" ] + [ "default", "overridexml", "quarkus", "quarkus-devmode" ] From 593c4df861957509169cd0fefeaf99a9bb8739e6 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 5 Dec 2023 10:48:48 +0100 Subject: [PATCH 130/376] keycloak_quarkus: add hostname-strict parameter --- roles/keycloak_quarkus/README.md | 9 +++++++++ roles/keycloak_quarkus/defaults/main.yml | 4 ++++ roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/templates/keycloak.conf.j2 | 1 + 4 files changed, 18 insertions(+) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index c32054e..9a04e1b 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -50,6 +50,13 @@ Role Defaults |`keycloak_quarkus_trust_store_password`| Password for the trust store | `""` | +* Hostname configuration + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_http_relative_path`| Set the path relative to / for serving resources. The path must start with a / | `/` | +|`keycloak_quarkus_hostname_strict`| Disables dynamically resolving the hostname from request headers | `true` | + * Database configuration @@ -118,6 +125,8 @@ Role Variables | Variable | Description | Required | |:---------|:------------|----------| |`keycloak_quarkus_admin_pass`| Password of console admin account | `yes` | +|`keycloak_quarkus_frontend_url`| Base URL for frontend URLs, including scheme, host, port and path | `no` | +|`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` | License diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index d5fcf90..a4f1d5e 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -63,6 +63,10 @@ keycloak_quarkus_admin_url: ### (set to `/auth` for retrocompatibility with pre-quarkus releases) keycloak_quarkus_http_relative_path: / +# Disables dynamically resolving the hostname from request headers. +# Should always be set to true in production, unless proxy verifies the Host header. +keycloak_quarkus_hostname_strict: true + # proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 89163aa..2d3dadf 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -288,3 +288,7 @@ argument_specs: default: true type: "bool" description: "Enable or disable XA transactions which may not be supported by some DBMS" + keycloak_quarkus_hostname_strict: + default: true + type: "bool" + description: "Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless proxy verifies the Host header." diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index ac2defe..b3b6787 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -41,6 +41,7 @@ hostname-port={{ keycloak_quarkus_port }} hostname-path={{ keycloak_quarkus_path }} {% endif %} hostname-admin-url={{ keycloak_quarkus_admin_url }} +hostname-strict={{ keycloak_quarkus_hostname_strict | lower }} # Cluster {% if keycloak_quarkus_ha_enabled %} From f365351abfd452625ee40a1c5a685241bcbae316 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 5 Dec 2023 19:53:26 +0100 Subject: [PATCH 131/376] use nginx instead of jbcs for https_revproxy test --- .github/workflows/ci.yml | 2 +- molecule/https_revproxy/molecule.yml | 2 -- molecule/https_revproxy/prepare.yml | 45 ++++++++++++++-------------- molecule/requirements.yml | 3 ++ 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6552ce1..afb1403 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "overridexml", "quarkus", "quarkus-devmode" ] + [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode" ] diff --git a/molecule/https_revproxy/molecule.yml b/molecule/https_revproxy/molecule.yml index 6a8790d..48bf375 100644 --- a/molecule/https_revproxy/molecule.yml +++ b/molecule/https_revproxy/molecule.yml @@ -41,8 +41,6 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" - REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID: "${PROD_JBOSSNETWORK_API_CLIENTID}" - REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET: "${PROD_JBOSSNETWORK_API_SECRET}" verifier: name: ansible scenario: diff --git a/molecule/https_revproxy/prepare.yml b/molecule/https_revproxy/prepare.yml index 5cdb135..a641257 100644 --- a/molecule/https_revproxy/prepare.yml +++ b/molecule/https_revproxy/prepare.yml @@ -3,7 +3,7 @@ hosts: all tasks: - name: Install sudo - ansible.builtin.yum: + ansible.builtin.dnf: name: sudo state: present @@ -14,36 +14,35 @@ - name: Prepare proxy hosts: proxy vars: - jbcs_mod_cluster_enable: True - jbcs_configure_firewalld: False - jbcs_offline_install: False - jbcs_bind_address: '*' - jbcs_proxy_pass: - - path: / - url: http://instance:8080/ - reverse_path: / - reverse_url: http://instance:8080/ - external_domain_name: proxy - rhn_username: "{{ lookup('env', 'REDHAT_PRODUCT_DOWNLOAD_CLIENT_ID') }}" - rhn_password: "{{ lookup('env', 'REDHAT_PRODUCT_DOWNLOAD_CLIENT_SECRET') }}" + nginx_proxy: | + location / { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://instance:8080; + } roles: - - middleware_automation.jbcs.jbcs + - elan.simple_nginx_reverse_proxy pre_tasks: - name: Create certificate request ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=proxy' delegate_to: localhost - changed_when: False - + changed_when: false + - name: Make certificate directory + ansible.builtin.file: + path: /etc/nginx/tls + state: directory - name: Copy certificates ansible.builtin.copy: src: "{{ item.name }}" dest: "{{ item.dest }}" mode: 0444 - become: True + become: true loop: - - { name: 'cert.pem', dest: '/etc/pki/tls/certs/proxy.crt' } - - { name: 'key.pem', dest: '/etc/pki/tls/private/proxy.key' } - - - name: update_ca_trust - command: update-ca-trust - become: True + - { name: 'cert.pem', dest: '/etc/nginx/tls/certificate.crt' } + - { name: 'key.pem', dest: '/etc/nginx/tls/certificate.key' } + - name: Update CA trust + ansible.builtin.command: update-ca-trust + changed_when: false + become: true diff --git a/molecule/requirements.yml b/molecule/requirements.yml index 5e39b59..c87fd9a 100644 --- a/molecule/requirements.yml +++ b/molecule/requirements.yml @@ -6,3 +6,6 @@ collections: - name: ansible.posix - name: community.docker version: ">=1.9.1" + +roles: + - name: elan.simple_nginx_reverse_proxy From 89944a6cd14e13a9dd9c590bd1ee486d269a881d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 5 Dec 2023 20:28:24 +0100 Subject: [PATCH 132/376] downstream: add rhbk bits --- .../keycloak_quarkus/meta/argument_specs.yml | 50 +++++++++++++++++++ roles/keycloak_quarkus/meta/main.yml | 1 + roles/keycloak_quarkus/tasks/install.yml | 42 +++++++++++++++- 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 2d3dadf..76384f4 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -292,3 +292,53 @@ argument_specs: default: true type: "bool" description: "Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless proxy verifies the Host header." + downstream: + options: + rhbk_version: + default: "22.0.6" + description: "Red Hat Build of Keycloak version" + type: "str" + rhbk_archive: + default: "rhbk-{{ rhbk_version }}.zip" + description: "Red Hat Build of Keycloak install archive filename" + type: "str" + rhbk_dest: + default: "/opt/rhbk" + description: "Root installation directory" + type: "str" + rhbk_installdir: + default: "{{ rhbk_dest }}/rhbk-{{ rhbk_version.split('.')[0] }}.{{ rhbk_version.split('.')[1] }}" + description: "Installation path for Red Hat Build of Keycloak" + type: "str" + rhbk_apply_patches: + default: false + description: "Install Red Hat Build of Keycloak most recent cumulative patch" + type: "bool" + rhbk_enable: + default: true + description: "Enable Red Hat Build of Keycloak installation" + type: "str" + rhbk_offline_install: + default: false + description: "Perform an offline install" + type: "bool" + rhbk_service_name: + default: "rhbk" + description: "systemd service name for Red Hat Build of Keycloak" + type: "str" + rhbk_service_desc: + default: "Red Hat Build of Keycloak" + description: "systemd description for Red Hat Build of Keycloak" + type: "str" + rhbk_patch_version: + required: false + description: "Red Hat Build of Keycloak latest cumulative patch version to apply; defaults to latest version when rhbk_apply_patches is True" + type: "str" + rhbk_patch_bundle: + default: "rhbk-{{ rhbk_patch_version | default('[0-9]+[.][0-9]+[.][0-9]+') }}-patch.zip" + description: "Red Hat Build of Keycloak patch archive filename" + type: "str" + rhbk_product_category: + default: "rhbk" + description: "JBossNetwork API category for Red Hat Build of Keycloak" + type: "str" diff --git a/roles/keycloak_quarkus/meta/main.yml b/roles/keycloak_quarkus/meta/main.yml index 469a71d..8d7331d 100644 --- a/roles/keycloak_quarkus/meta/main.yml +++ b/roles/keycloak_quarkus/meta/main.yml @@ -24,3 +24,4 @@ galaxy_info: - authentication - identity - security + - rhbk diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 887aa31..25106f9 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -57,11 +57,51 @@ dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" mode: 0640 delegate_to: localhost + run_once: true when: - archive_path is defined - archive_path.stat is defined - not archive_path.stat.exists - not keycloak.offline_install + - not rhbk_enable is defined or not rhbk_enable + +- name: Perform download from RHN using JBoss Network API + delegate_to: localhost + run_once: true + when: + - archive_path is defined + - archive_path.stat is defined + - not archive_path.stat.exists + - rhbk_enable is defined and rhbk_enable + - not keycloak.offline_install + block: + - name: Retrieve product download using JBoss Network API + middleware_automation.common.product_search: + client_id: "{{ rhn_username }}" + client_secret: "{{ rhn_password }}" + product_type: DISTRIBUTION + product_version: "{{ rhbk_version }}" + product_category: "{{ rhbk_product_category }}" + register: rhn_products + no_log: "{{ omit_rhn_output | default(true) }}" + delegate_to: localhost + run_once: true + + - name: Determine install zipfile from search results + ansible.builtin.set_fact: + rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/' + rhbk_archive + '$') }}" + delegate_to: localhost + run_once: true + + - name: Download Red Hat Build of Keycloak + middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user + client_id: "{{ rhn_username }}" + client_secret: "{{ rhn_password }}" + product_id: "{{ (rhn_filtered_products | first).id }}" + dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" + no_log: "{{ omit_rhn_output | default(true) }}" + delegate_to: localhost + run_once: true - name: Check downloaded archive ansible.builtin.stat: @@ -76,7 +116,7 @@ dest: "{{ archive }}" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0750 + mode: 0640 register: new_version_downloaded when: - not archive_path.stat.exists From acdee7fa63b7321a35167754f6989a497b7812c4 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 6 Dec 2023 15:40:28 +0100 Subject: [PATCH 133/376] ci: downstream arg specs for realm role --- roles/keycloak_realm/meta/argument_specs.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/roles/keycloak_realm/meta/argument_specs.yml b/roles/keycloak_realm/meta/argument_specs.yml index bc606ba..ca174dc 100644 --- a/roles/keycloak_realm/meta/argument_specs.yml +++ b/roles/keycloak_realm/meta/argument_specs.yml @@ -113,3 +113,23 @@ argument_specs: default: true description: "Enable Red Hat Single Sign-on installation" type: "str" + rhbk_version: + default: "22.0.6" + description: "Red Hat Build of Keycloak version" + type: "str" + rhbk_archive: + default: "rhbk-{{ rhbk_version }}.zip" + description: "Red Hat Build of Keycloak install archive filename" + type: "str" + rhbk_dest: + default: "/opt/rhbk" + description: "Root installation directory" + type: "str" + rhbk_installdir: + default: "{{ rhbk_dest }}/rhbk-{{ rhbk_version.split('.')[0] }}.{{ rhbk_version.split('.')[1] }}" + description: "Installation path for Red Hat Build of Keycloak" + type: "str" + rhbk_enable: + default: true + description: "Enable Red Hat Build of Keycloak installation" + type: "str" From 5b8fcb67dc2b0562b18aa255399e2ecf648f1ddb Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 6 Dec 2023 16:03:37 +0100 Subject: [PATCH 134/376] ci: update sample quarkus playbook --- playbooks/keycloak_quarkus.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index 13bbce5..02e356f 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -5,7 +5,6 @@ keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_quarkus_host: localhost keycloak_quarkus_port: 8443 - keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_key_file: conf/key.pem From ac0b42145651ce1aa3f37e8dcfc1a2014e3e662e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 6 Dec 2023 16:34:55 +0100 Subject: [PATCH 135/376] downstream: fix rhbk install path --- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- roles/keycloak_quarkus/tasks/main.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 76384f4..6fdd108 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -307,7 +307,7 @@ argument_specs: description: "Root installation directory" type: "str" rhbk_installdir: - default: "{{ rhbk_dest }}/rhbk-{{ rhbk_version.split('.')[0] }}.{{ rhbk_version.split('.')[1] }}" + default: "{{ rhbk_dest }}/rhbk-{{ rhbk_version }}" description: "Installation path for Red Hat Build of Keycloak" type: "str" rhbk_apply_patches: diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 93a68c0..71582f8 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -41,7 +41,7 @@ mode: 0644 become: true notify: - - restart keycloak + - restart keycloak - name: Ensure logdirectory exists ansible.builtin.file: From a23bf4c540668c85172d04fc4250742fa335d9b5 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 6 Dec 2023 18:24:29 +0100 Subject: [PATCH 136/376] ci: downstream use correct version --- molecule/quarkus/prepare.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 44d2492..f6a556d 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -1,6 +1,8 @@ --- - name: Prepare hosts: all + vars: + version: "{{ '22.0.6' if rhbk_enable is defined and rhbk_enable else '23.0.1' }}" tasks: - name: Install sudo ansible.builtin.yum: @@ -19,13 +21,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: /opt/keycloak/keycloak-23.0.1/conf/ + path: "/opt/keycloak/keycloak-{{ version }}/conf/" mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-23.0.1/conf/{{ item }}" + dest: "/opt/keycloak/keycloak-{{ version }}/conf/{{ item }}" mode: 0444 loop: - cert.pem From d469d5df8b9709b55dbd7e2eb76d69c9726c4e00 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 6 Dec 2023 18:52:46 +0100 Subject: [PATCH 137/376] ci: downstream update sample playbooks --- playbooks/keycloak_quarkus.yml | 1 + playbooks/keycloak_quarkus_dev.yml | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index 02e356f..cec5188 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -9,5 +9,6 @@ keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_key_file: conf/key.pem keycloak_quarkus_cert_file: conf/cert.pem + keycloak_quarkus_proxy_mode: none roles: - middleware_automation.keycloak.keycloak_quarkus diff --git a/playbooks/keycloak_quarkus_dev.yml b/playbooks/keycloak_quarkus_dev.yml index 634296d..533db79 100644 --- a/playbooks/keycloak_quarkus_dev.yml +++ b/playbooks/keycloak_quarkus_dev.yml @@ -5,7 +5,6 @@ keycloak_admin_password: "remembertochangeme" keycloak_quarkus_host: localhost keycloak_quarkus_port: 8080 - keycloak_quarkus_http_relative_path: '' keycloak_quarkus_log: file keycloak_quarkus_start_dev: true keycloak_quarkus_proxy_mode: none From 0fbf454279d34a21a8053c525a27ab448faed9b9 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 7 Dec 2023 11:00:28 +0100 Subject: [PATCH 138/376] ci: test alternate certs dir --- molecule/quarkus/converge.yml | 4 ++-- molecule/quarkus/prepare.yml | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 686494d..1b989ce 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -8,8 +8,8 @@ keycloak_quarkus_host: instance keycloak_quarkus_log: file keycloak_quarkus_https_key_file_enabled: True - keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/key.pem" - keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/cert.pem" + keycloak_quarkus_key_file: "/opt/keycloak/certs/key.pem" + keycloak_quarkus_cert_file: "/opt/keycloak/certs/cert.pem" keycloak_quarkus_log_target: /tmp/keycloak roles: - role: keycloak_quarkus diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index f6a556d..13d85a8 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -1,8 +1,6 @@ --- - name: Prepare hosts: all - vars: - version: "{{ '22.0.6' if rhbk_enable is defined and rhbk_enable else '23.0.1' }}" tasks: - name: Install sudo ansible.builtin.yum: @@ -21,13 +19,13 @@ - name: Create conf directory # risky-file-permissions in test user account does not exist yet ansible.builtin.file: state: directory - path: "/opt/keycloak/keycloak-{{ version }}/conf/" + path: "/opt/keycloak/certs/" mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item }}" - dest: "/opt/keycloak/keycloak-{{ version }}/conf/{{ item }}" + dest: "/opt/keycloak/certs/{{ item }}" mode: 0444 loop: - cert.pem From 98b82ccb4fb8e85e53c9494895a6ead71666665c Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 7 Dec 2023 11:15:12 +0100 Subject: [PATCH 139/376] ci: runner playbook no keypair --- playbooks/keycloak_quarkus.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index cec5188..f2649a5 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -6,9 +6,6 @@ keycloak_quarkus_host: localhost keycloak_quarkus_port: 8443 keycloak_quarkus_log: file - keycloak_quarkus_https_key_file_enabled: true - keycloak_quarkus_key_file: conf/key.pem - keycloak_quarkus_cert_file: conf/cert.pem keycloak_quarkus_proxy_mode: none roles: - middleware_automation.keycloak.keycloak_quarkus From 473fb212c3946606c201de89cd618632a62536bf Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Thu, 7 Dec 2023 14:30:17 +0000 Subject: [PATCH 140/376] Update changelog for release 2.0.1 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 14 ++++++++++++++ changelogs/changelog.yaml | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fa6fdea..274cfa3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,20 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.0.1 +====== + +Minor Changes +------------- + +- keycloak_quarkus: add hostname-strict parameter `#139 `_ +- keycloak_quarkus: update to version 23.0.1 `#133 `_ + +Bugfixes +-------- + +- keycloak_quarkus: template requires lowercase boolean values `#138 `_ + v2.0.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index e3ec06e..7d19d7f 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -341,3 +341,21 @@ releases: - 122.yaml - 124.yaml release_date: '2023-11-20' + 2.0.1: + changes: + bugfixes: + - 'keycloak_quarkus: template requires lowercase boolean values `#138 `_ + + ' + minor_changes: + - 'keycloak_quarkus: add hostname-strict parameter `#139 `_ + + ' + - 'keycloak_quarkus: update to version 23.0.1 `#133 `_ + + ' + fragments: + - 133.yaml + - 138.yaml + - 139.yaml + release_date: '2023-12-07' From db19fd5d19a1eaa62bbbcc9d17012812f5400a24 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Thu, 7 Dec 2023 14:30:27 +0000 Subject: [PATCH 141/376] Bump version to 2.0.2 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index bd77fe6..ac09faa 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.0.1" +version: "2.0.2" readme: README.md authors: - Romain Pelisse From ed6dbd60fb9c358daf26907c0773a00344183f92 Mon Sep 17 00:00:00 2001 From: Ranabir Chakraborty Date: Mon, 11 Dec 2023 22:12:39 +0530 Subject: [PATCH 142/376] AMW-170 Ansible Hub links for rhbk are broken --- README.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index d93231f..efcd597 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ > **_NOTE:_ If you are Red Hat customer, install `redhat.sso` from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection.** -Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on). +Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on). ## Ansible version compatibility @@ -44,25 +44,25 @@ A requirement file is provided to install: pip install -r requirements.txt - + ### Included roles * [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service. * [`keycloak_realm`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md): role for configuring a realm, user federation(s), clients and users, in an installed service. * [`keycloak_quarkus`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_quarkus/README.md): role for installing the quarkus variant of keycloak (>= 17.0.0). - + ## Usage ### Install Playbook - + * [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs based on the defined variables (using most defaults). Both playbooks include the `keycloak` role, with different settings, as described in the following sections. For full service configuration details, refer to the [keycloak role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md). - + #### Install from controller node (offline) @@ -85,7 +85,7 @@ It is possible to perform downloads from alternate sources, using the `keycloak_ ### Example installation command -Execute the following command from the source root directory +Execute the following command from the source root directory ``` ansible-playbook -i -e @rhn-creds.yml playbooks/keycloak.yml -e keycloak_admin_password= @@ -106,9 +106,9 @@ Note: when deploying clustered configurations, all hosts belonging to the cluste ### Config Playbook - + [`playbooks/keycloak_realm.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak_realm.yml) creates or updates provided realm, user federation(s), client(s), client role(s) and client user(s). - + ### Example configuration command @@ -126,9 +126,9 @@ ansible-playbook -i playbooks/keycloak_realm.yml -e keycloak_adm [keycloak] localhost ansible_connection=local ``` - + For full configuration details, refer to the [keycloak_realm role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md). - + @@ -137,6 +137,7 @@ For full configuration details, refer to the [keycloak_realm role README](https: ## License Apache License v2.0 or later - + See [LICENSE](LICENSE) to view the full text. + From 83bcb6712adb24cd4904aa8c2c49287ec99a1aa8 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 19 Dec 2023 09:30:30 +0100 Subject: [PATCH 143/376] keycloak_quarkus: add systemd control options * keycloak_quarkus_service_restart_always * keycloak_quarkus_service_restart_on_failure * keycloak_quarkus_service_restartsec --- roles/keycloak_quarkus/README.md | 7 +++++-- roles/keycloak_quarkus/defaults/main.yml | 3 +++ roles/keycloak_quarkus/meta/argument_specs.yml | 12 ++++++++++++ roles/keycloak_quarkus/templates/keycloak.service.j2 | 7 +++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 9a04e1b..8fa1a75 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -31,6 +31,9 @@ Role Defaults |`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7600` | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` | +|`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` | +|`keycloak_quarkus_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` | +|`keycloak_quarkus_service_restartsec`| systemd RestartSec | `10s` | |`keycloak_quarkus_service_pidfile`| Pid file path for service | `/run/keycloak.pid` | |`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | @@ -79,7 +82,7 @@ Role Defaults |`keycloak_quarkus_ispn_sasl_mechanism` | Infinispan auth mechanism | `SCRAM-SHA-512` | |`keycloak_quarkus_ispn_use_ssl` | Whether infinispan uses TLS connection | `false` | |`keycloak_quarkus_ispn_trust_store_path` | Path to infinispan server trust certificate | `/etc/pki/java/cacerts` | -|`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` | +|`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` | * Install options @@ -87,7 +90,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| -|`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| +|`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| |`keycloak_quarkus_version`| keycloak.org package version | `23.0.1` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index a4f1d5e..1a1382f 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -19,6 +19,9 @@ keycloak_quarkus_service_user: keycloak keycloak_quarkus_service_group: keycloak keycloak_quarkus_service_pidfile: "/run/keycloak/keycloak.pid" keycloak_quarkus_configure_firewalld: false +keycloak_quarkus_service_restart_always: false +keycloak_quarkus_service_restart_on_failure: false +keycloak_quarkus_service_restartsec: "10s" ### administrator console password keycloak_quarkus_admin_user: admin diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 6fdd108..f616611 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -69,6 +69,18 @@ argument_specs: default: false description: "Ensure firewalld is running and configure keycloak ports" type: "bool" + keycloak_service_restart_always: + default: false + description: "systemd restart always behavior of service" + type: "bool" + keycloak_service_restart_on_failure: + default: false + description: "systemd restart on-failure behavior of service" + type: "bool" + keycloak_service_restartsec: + default: "10s" + description: "systemd RestartSec for service" + type: "str" keycloak_quarkus_admin_user: default: "admin" description: "Administration console user account" diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index f7ffc1c..1854463 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -13,6 +13,13 @@ ExecStart={{ keycloak.home }}/bin/kc.sh start-dev ExecStart={{ keycloak.home }}/bin/kc.sh start --log={{ keycloak_quarkus_log }} {% endif %} User={{ keycloak.service_user }} +Group={{ keycloak.service_group }} +{% if keycloak_quarkus_service_restart_always %} +Restart=always +{% elif keycloak_quarkus_service_restart_on_failure %} +Restart=on-failure +{% endif %} +RestartSec={{ keycloak_quarkus_service_restartsec }} [Install] WantedBy=multi-user.target From 1d5ce87c16a69ceacd16790e3cd5f69c1fc72846 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 19 Dec 2023 09:55:02 +0100 Subject: [PATCH 144/376] keycloak_quarkus: Remove legacy (?) `keycloak_management_url` --- roles/keycloak_quarkus/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 8fa1a75..e419d89 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -111,7 +111,6 @@ Role Defaults |`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` | |`keycloak_force_install` | Remove pre-existing versions of service | `False` | |`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_quarkus_host }}:{{ keycloak_http_port }}` | -|`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_quarkus_host }}:{{ keycloak_management_http_port }}` | |`keycloak_quarkus_log`| Enable one or more log handlers in a comma-separated list | `file` | |`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` | |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | From bfd9db6703daf0550f3910c44840331bc04a345b Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 8 Jan 2024 17:42:30 +0100 Subject: [PATCH 145/376] fix/147: keycloak_quarkus: RBKC: Add support for sqlserver jdbc driver --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 5 ++++- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- roles/keycloak_quarkus/tasks/install.yml | 6 ++++++ roles/keycloak_quarkus/tasks/jdbc_driver.yml | 12 ++++++++++++ 5 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 roles/keycloak_quarkus/tasks/jdbc_driver.yml diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index c2338c3..acdb121 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -55,7 +55,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_jdbc_engine` | Database engine [mariadb,postres] | `postgres` | +|`keycloak_quarkus_jdbc_engine` | Database engine [mariadb,postres,mssql] | `postgres` | |`keycloak_quarkus_db_user` | User for database connection | `keycloak-user` | |`keycloak_quarkus_db_pass` | Password for database connection | `keycloak-pass` | |`keycloak_quarkus_jdbc_url` | JDBC URL for connecting to database | `jdbc:postgresql://localhost:5432/keycloak` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 51ca792..1c7a41b 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -97,7 +97,10 @@ keycloak_quarkus_default_jdbc: mariadb: url: 'jdbc:mariadb://localhost:3306/keycloak' version: 2.7.4 - + mssql: + url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;' + version: 12.2.0 + driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar" # cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/22.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver ### logging configuration keycloak_quarkus_log: file keycloak_quarkus_log_level: info diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index d260910..accd770 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -234,7 +234,7 @@ argument_specs: keycloak_quarkus_jdbc_engine: # line 56 of defaults/main.yml default: "postgres" - description: "Database engine [mariadb,postres]" + description: "Database engine [mariadb,postres,mssql]" type: "str" keycloak_quarkus_db_user: # line 58 of defaults/main.yml diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index b1ea1ee..ebd8585 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -109,3 +109,9 @@ msg: "{{ keycloak.home }} already exists and version unchanged, skipping decompression" when: - (not new_version_downloaded.changed) and path_to_workdir.stat.exists + +- name: "Install {{ keycloak_quarkus_jdbc_engine }} JDBC driver" + ansible.builtin.include_tasks: jdbc_driver.yml + when: + - rhbk_enable is defined and rhbk_enable + - keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url is defined diff --git a/roles/keycloak_quarkus/tasks/jdbc_driver.yml b/roles/keycloak_quarkus/tasks/jdbc_driver.yml new file mode 100644 index 0000000..0d03030 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/jdbc_driver.yml @@ -0,0 +1,12 @@ +--- + +- name: "Retrieve JDBC Driver from {{ keycloak_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url }}" + ansible.builtin.get_url: + url: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url }}" + dest: "{{ keycloak.home }}/providers" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: 0640 + become: true + notify: + - restart keycloak From b057f0297ac6c79794bbf13f5318a85798fe5073 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 9 Jan 2024 08:20:02 +0100 Subject: [PATCH 146/376] fix/#151: keycloak_quarkus: allow configuration of `hostname-strict-backchannel` --- roles/keycloak_quarkus/README.md | 1 + roles/keycloak_quarkus/defaults/main.yml | 3 +++ roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/templates/keycloak.conf.j2 | 1 + 4 files changed, 9 insertions(+) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 9a04e1b..623ca28 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -56,6 +56,7 @@ Role Defaults |:---------|:------------|:--------| |`keycloak_quarkus_http_relative_path`| Set the path relative to / for serving resources. The path must start with a / | `/` | |`keycloak_quarkus_hostname_strict`| Disables dynamically resolving the hostname from request headers | `true` | +|`keycloak_quarkus_hostname_strict_backchannel`| By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled. | `false` | * Database configuration diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index a4f1d5e..46cce41 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -66,6 +66,9 @@ keycloak_quarkus_http_relative_path: / # Disables dynamically resolving the hostname from request headers. # Should always be set to true in production, unless proxy verifies the Host header. keycloak_quarkus_hostname_strict: true +# By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. +# If all applications use the public URL this option should be enabled. +keycloak_quarkus_hostname_strict_backchannel: false # proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 6fdd108..e975696 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -292,6 +292,10 @@ argument_specs: default: true type: "bool" description: "Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless proxy verifies the Host header." + keycloak_quarkus_hostname_strict_backchannel: + default: false + type: "bool" + description: "By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled." downstream: options: rhbk_version: diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index b3b6787..8ea545d 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -42,6 +42,7 @@ hostname-path={{ keycloak_quarkus_path }} {% endif %} hostname-admin-url={{ keycloak_quarkus_admin_url }} hostname-strict={{ keycloak_quarkus_hostname_strict | lower }} +hostname-strict-backchannel={{ keycloak_quarkus_hostname_strict_backchannel | lower }} # Cluster {% if keycloak_quarkus_ha_enabled %} From b1b31427d50b88f0e9f039b54a046245290338f5 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 10 Jan 2024 16:26:46 +0100 Subject: [PATCH 147/376] fix/#153: keycloak_quarkus: Use `keycloak_quarkus_java_opts` Note: when multiple -X options of the same kind are provided, the last option seems to take precendence as per : > java -Xmx1G -XX:+PrintFlagsFinal -Xmx2G 2>/dev/null | grep MaxHeapSize --- roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index a3fdf57..b028085 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -3,3 +3,4 @@ KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' PATH={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin JAVA_HOME={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }} +JAVA_OPTS_APPEND={{ keycloak_quarkus_java_opts }} \ No newline at end of file From 922e4c10f5557b341aa929da03d2f68ef8a86235 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 15 Jan 2024 14:40:46 +0100 Subject: [PATCH 148/376] #145 - CR changes --- galaxy.yml | 1 + roles/keycloak_quarkus/README.md | 1 - roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index ac09faa..21cb096 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -7,6 +7,7 @@ authors: - Romain Pelisse - Guido Grazioli - Pavan Kumar Motaparthi + - Helmut Wolf description: Install and configure a keycloak, or Red Hat Single Sign-on, service. license_file: "LICENSE" tags: diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index e419d89..9fdb2e0 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -90,7 +90,6 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| -|`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download//`| |`keycloak_quarkus_version`| keycloak.org package version | `23.0.1` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index f616611..3ad24f8 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -71,7 +71,7 @@ argument_specs: type: "bool" keycloak_service_restart_always: default: false - description: "systemd restart always behavior of service" + description: "systemd restart always behavior of service; takes precedence over keycloak_service_restart_on_failure if true" type: "bool" keycloak_service_restart_on_failure: default: false From 8adc018cb317fe172d783f731e5c347b884a1aae Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 8 Jan 2024 18:19:00 +0100 Subject: [PATCH 149/376] fix/#149: keycloak_quarkus: Allow ports <1024 (e.g., :443) --- roles/keycloak_quarkus/templates/keycloak.service.j2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 1854463..a529c5b 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -20,6 +20,9 @@ Restart=always Restart=on-failure {% endif %} RestartSec={{ keycloak_quarkus_service_restartsec }} +{% if keycloak_quarkus_http_port|int < 1024 or keycloak_quarkus_https_port|int < 1024 %} +AmbientCapabilities=CAP_NET_BIND_SERVICE +{% endif %} [Install] WantedBy=multi-user.target From 30309582f37439893c33939cd2081845f6e7b63b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 16 Jan 2024 09:17:47 +0100 Subject: [PATCH 150/376] Update README.md --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0cb62c2..0cd3ba0 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,10 @@ [![Build Status](https://github.com/ansible-middleware/keycloak/workflows/CI/badge.svg?branch=main)](https://github.com/ansible-middleware/keycloak/actions/workflows/ci.yml) -> **_NOTE:_ If you are Red Hat customer, install `redhat.sso` from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection.** +> **_NOTE:_ If you are Red Hat customer, install `redhat.sso` (for Red Hat Single Sign-On) or `redhat.rhbk` (for Red Hat Build of Keycloak) from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection.** -Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on). +Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on) / [Red Hat Build of Keycloak](https://access.redhat.com/products/red-hat-build-of-keycloak). ## Ansible version compatibility @@ -47,7 +47,7 @@ A requirement file is provided to install: ### Included roles -* [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service. +* [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service (keycloak <= 19.0). * [`keycloak_realm`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md): role for configuring a realm, user federation(s), clients and users, in an installed service. * [`keycloak_quarkus`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_quarkus/README.md): role for installing the quarkus variant of keycloak (>= 17.0.0). @@ -57,8 +57,9 @@ A requirement file is provided to install: ### Install Playbook -* [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs based on the defined variables (using most defaults). - +* [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs keycloak legacy based on the defined variables (using most defaults). +* [`playbooks/keycloak_quarkus.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak_quarkus.yml) installs keycloak >= 17 based on the defined variables (using most defaults). + Both playbooks include the `keycloak` role, with different settings, as described in the following sections. For full service configuration details, refer to the [keycloak role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md). From 2985f808ea4cb62019a294d399f454fbe4a5c306 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 17 Jan 2024 08:50:24 +0000 Subject: [PATCH 151/376] Update changelog for release 2.0.2 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 16 ++++++++++++++++ changelogs/changelog.yaml | 27 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 274cfa3..c3a46da 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,22 @@ middleware_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.0.2 +====== + +Minor Changes +------------- + +- keycloak_quarkus: Add support for sqlserver jdbc driver `#148 `_ +- keycloak_quarkus: allow configuration of ``hostname-strict-backchannel`` `#152 `_ +- keycloak_quarkus: systemd restart behavior `#145 `_ + +Bugfixes +-------- + +- keycloak_quarkus: Use ``keycloak_quarkus_java_opts`` `#154 `_ +- keycloak_quarkus: allow ports <1024 (e.g. :443) in systemd unit `#150 `_ + v2.0.1 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 7d19d7f..7d684cd 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -359,3 +359,30 @@ releases: - 138.yaml - 139.yaml release_date: '2023-12-07' + 2.0.2: + changes: + bugfixes: + - 'keycloak_quarkus: Use ``keycloak_quarkus_java_opts`` `#154 `_ + + ' + - 'keycloak_quarkus: allow ports <1024 (e.g. :443) in systemd unit `#150 `_ + + ' + minor_changes: + - 'keycloak_quarkus: Add support for sqlserver jdbc driver `#148 `_ + + ' + - 'keycloak_quarkus: allow configuration of ``hostname-strict-backchannel`` + `#152 `_ + + ' + - 'keycloak_quarkus: systemd restart behavior `#145 `_ + + ' + fragments: + - 145.yaml + - 148.yaml + - 150.yaml + - 152.yaml + - 154.yaml + release_date: '2024-01-17' From e866d1f4e417a0d7d02216ebdff5f8554980f401 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 17 Jan 2024 08:50:31 +0000 Subject: [PATCH 152/376] Bump version to 2.0.3 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 21cb096..b5c1a2b 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.0.2" +version: "2.0.3" readme: README.md authors: - Romain Pelisse From 688ec956fc6df2a77e0eb81b133896cf673ecf82 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 17 Jan 2024 16:51:24 +0100 Subject: [PATCH 153/376] fix #156: quarkus 3 ispn config renamings --- galaxy.yml | 2 +- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 6 +++--- .../templates/quarkus.properties.j2 | 14 +++++++++----- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index b5c1a2b..6a1d110 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.0.3" +version: "2.1.0" readme: README.md authors: - Romain Pelisse diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index e0a189b..cd720a5 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -79,7 +79,7 @@ Role Defaults |:---------|:------------|:--------| |`keycloak_quarkus_ispn_user` | Username for connecting to infinispan | `supervisor` | |`keycloak_quarkus_ispn_pass` | Password for connecting to infinispan | `supervisor` | -|`keycloak_quarkus_ispn_url` | URL for connecting to infinispan | `localhost` | +|`keycloak_quarkus_ispn_hosts` | host name/port for connecting to infinispan, eg. host1:11222;host2:11222 | `localhost:11222` | |`keycloak_quarkus_ispn_sasl_mechanism` | Infinispan auth mechanism | `SCRAM-SHA-512` | |`keycloak_quarkus_ispn_use_ssl` | Whether infinispan uses TLS connection | `false` | |`keycloak_quarkus_ispn_trust_store_path` | Path to infinispan server trust certificate | `/etc/pki/java/cacerts` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index bcc03ee..da42960 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -85,7 +85,7 @@ keycloak_quarkus_health_enabled: true ### infinispan remote caches access (hotrod) keycloak_quarkus_ispn_user: supervisor keycloak_quarkus_ispn_pass: supervisor -keycloak_quarkus_ispn_url: localhost +keycloak_quarkus_ispn_hosts: "localhost:11222" keycloak_quarkus_ispn_sasl_mechanism: SCRAM-SHA-512 keycloak_quarkus_ispn_use_ssl: false # if ssl is enabled, import ispn server certificate here diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 22a9b45..37c873e 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -218,10 +218,10 @@ argument_specs: default: "supervisor" description: "Password for connecting to infinispan" type: "str" - keycloak_quarkus_ispn_url: + keycloak_quarkus_ispn_hosts: # line 48 of defaults/main.yml - default: "localhost" - description: "URL for connecting to infinispan" + default: "localhost:11222" + description: "host name/port for connecting to infinispan, eg. host1:11222;host2:11222" type: "str" keycloak_quarkus_ispn_sasl_mechanism: # line 49 of defaults/main.yml diff --git a/roles/keycloak_quarkus/templates/quarkus.properties.j2 b/roles/keycloak_quarkus/templates/quarkus.properties.j2 index cf133a3..cb2f2d3 100644 --- a/roles/keycloak_quarkus/templates/quarkus.properties.j2 +++ b/roles/keycloak_quarkus/templates/quarkus.properties.j2 @@ -1,10 +1,16 @@ # {{ ansible_managed }} {% if keycloak_quarkus_ha_enabled %} -quarkus.infinispan-client.server-list={{ keycloak_quarkus_ispn_url }} -quarkus.infinispan-client.client-intelligence=HASH_DISTRIBUTION_AWARE -quarkus.infinispan-client.use-auth=true +{% if not rhbk_enable or keycloak_quarkus_version.split('.')[0]|int < 22 %} +quarkus.infinispan-client.server-list={{ keycloak_quarkus_ispn_hosts }} quarkus.infinispan-client.auth-username={{ keycloak_quarkus_ispn_user }} quarkus.infinispan-client.auth-password={{ keycloak_quarkus_ispn_pass }} +{% else %} +quarkus.infinispan-client.hosts={{ keycloak_quarkus_ispn_hosts }} +quarkus.infinispan-client.username={{ keycloak_quarkus_ispn_user }} +quarkus.infinispan-client.password={{ keycloak_quarkus_ispn_pass }} +{% endif %} +quarkus.infinispan-client.client-intelligence=HASH_DISTRIBUTION_AWARE +quarkus.infinispan-client.use-auth=true quarkus.infinispan-client.auth-realm=default quarkus.infinispan-client.auth-server-name=infinispan quarkus.infinispan-client.sasl-mechanism={{ keycloak_quarkus_ispn_sasl_mechanism }} @@ -14,6 +20,4 @@ quarkus.infinispan-client.trust-store-password={{ keycloak_quarkus_ispn_trust_st quarkus.infinispan-client.trust-store-type=jks {% endif %} #quarkus.infinispan-client.use-schema-registration=true -#quarkus.infinispan-client.auth-client-subject -#quarkus.infinispan-client.auth-callback-handler {% endif %} \ No newline at end of file From 63f83d77445feb698f4ea784ea370489f781ee14 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 17 Jan 2024 17:22:06 +0100 Subject: [PATCH 154/376] add initial support for templating `cache-ispn.xml` --- roles/keycloak_quarkus/tasks/main.yml | 11 +++ .../keycloak_quarkus/templates/cache-ispn.xml | 85 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 roles/keycloak_quarkus/templates/cache-ispn.xml diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 71582f8..394cf3b 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -43,6 +43,17 @@ notify: - restart keycloak +- name: "Configure infinispan config for keycloak service" + ansible.builtin.template: + src: cache-ispn.xml + dest: "{{ keycloak.home }}/conf/cache-ispn.xml" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: 0644 + become: true + notify: + - restart keycloak + - name: Ensure logdirectory exists ansible.builtin.file: state: directory diff --git a/roles/keycloak_quarkus/templates/cache-ispn.xml b/roles/keycloak_quarkus/templates/cache-ispn.xml new file mode 100644 index 0000000..20a1af7 --- /dev/null +++ b/roles/keycloak_quarkus/templates/cache-ispn.xml @@ -0,0 +1,85 @@ +# {{ ansible_managed }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 0c5047bcc109393e63a707d903edea0d0f82bdb9 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 22 Jan 2024 13:53:28 +0100 Subject: [PATCH 155/376] feature/160: keycloak_quarkus: Allow easier log setting configuration --- roles/keycloak_quarkus/README.md | 3 +++ roles/keycloak_quarkus/defaults/main.yml | 3 +++ roles/keycloak_quarkus/meta/argument_specs.yml | 12 ++++++++++++ .../keycloak_quarkus/templates/quarkus.properties.j2 | 5 ++++- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index cd720a5..80eef90 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -116,6 +116,9 @@ Role Defaults |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | |`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | |`keycloak_quarkus_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | +|`keycloak_quarkus_log_max_file_size`| Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): [0-9]+[KkMmGgTtPpEeZzYy]?. If no suffix is given, assume bytes." | `10M` +|`keycloak_quarkus_log_max_backup_index`| Set the maximum number of archived log files to keep" | `10` +|`keycloak_quarkus_log_file_suffix`| Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with `.zip` or `.gz`, the rotation file will also be compressed." | `.yyyy-MM-dd.zip` |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index da42960..fa85d98 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -117,3 +117,6 @@ keycloak_quarkus_log_level: info keycloak_quarkus_log_file: data/log/keycloak.log keycloak_quarkus_log_format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' keycloak_quarkus_log_target: /var/log/keycloak +keycloak_quarkus_log_max_file_size: 10M +keycloak_quarkus_log_max_backup_index: 10 +keycloak_quarkus_log_file_suffix: '.yyyy-MM-dd.zip' diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 37c873e..f7b49e3 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -288,6 +288,18 @@ argument_specs: default: '/var/log/keycloak' type: "str" description: "Set the destination of the keycloak log folder link" + keycloak_quarkus_log_max_file_size: + default: 10M + type: "str" + description: "Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): [0-9]+[KkMmGgTtPpEeZzYy]?. If no suffix is given, assume bytes." + keycloak_quarkus_log_max_backup_index: + default: 10 + type: "str" + description: "Set the maximum number of archived log files to keep" + keycloak_quarkus_log_file_suffix: + default: '.yyyy-MM-dd.zip' + type: "str" + description: "Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with .zip or .gz, the rotation file will also be compressed." keycloak_quarkus_proxy_mode: default: 'edge' type: "str" diff --git a/roles/keycloak_quarkus/templates/quarkus.properties.j2 b/roles/keycloak_quarkus/templates/quarkus.properties.j2 index cb2f2d3..f8502f2 100644 --- a/roles/keycloak_quarkus/templates/quarkus.properties.j2 +++ b/roles/keycloak_quarkus/templates/quarkus.properties.j2 @@ -20,4 +20,7 @@ quarkus.infinispan-client.trust-store-password={{ keycloak_quarkus_ispn_trust_st quarkus.infinispan-client.trust-store-type=jks {% endif %} #quarkus.infinispan-client.use-schema-registration=true -{% endif %} \ No newline at end of file +{% endif %} +quarkus.log.file.rotation.max-file-size={{ keycloak_quarkus_log_max_file_size }} +quarkus.log.file.rotation.max-backup-index={{ keycloak_quarkus_log_max_backup_index }} +quarkus.log.file.rotation.file-suffix={{ keycloak_quarkus_log_file_suffix }} \ No newline at end of file From c2009a0a12d28e6fa8114d22c11a3214caceea7b Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Thu, 8 Feb 2024 16:10:32 +0100 Subject: [PATCH 156/376] feature/160: CR changes --- roles/keycloak_quarkus/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 80eef90..1f222a6 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -116,9 +116,9 @@ Role Defaults |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | |`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | |`keycloak_quarkus_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | -|`keycloak_quarkus_log_max_file_size`| Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): [0-9]+[KkMmGgTtPpEeZzYy]?. If no suffix is given, assume bytes." | `10M` -|`keycloak_quarkus_log_max_backup_index`| Set the maximum number of archived log files to keep" | `10` -|`keycloak_quarkus_log_file_suffix`| Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with `.zip` or `.gz`, the rotation file will also be compressed." | `.yyyy-MM-dd.zip` +|`keycloak_quarkus_log_max_file_size`| Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): `[0-9]+[KkMmGgTtPpEeZzYy]?`. If no suffix is given, assume bytes. | `10M` | +|`keycloak_quarkus_log_max_backup_index`| Set the maximum number of archived log files to keep" | `10` | +|`keycloak_quarkus_log_file_suffix`| Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with `.zip` or `.gz`, the rotation file will also be compressed. | `.yyyy-MM-dd.zip` | |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | From e0d4920a490c8248174ad70b536c627331b342ef Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 22 Jan 2024 14:06:38 +0100 Subject: [PATCH 157/376] feature/162: keycloak_quarkus: make `spi-sticky-session-encoder-infinispan-should-attach-route` configurable in `keycloak.conf` --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 3 +++ roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/templates/keycloak.conf.j2 | 3 +-- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index cd720a5..8a32909 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -119,7 +119,7 @@ Role Defaults |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | - +|`keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route`| If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy | `True` | Role Variables -------------- diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index da42960..a2141bc 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -79,6 +79,9 @@ keycloak_quarkus_proxy_mode: edge # disable xa transactions keycloak_quarkus_transaction_xa_enabled: true +# If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy +keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: true + keycloak_quarkus_metrics_enabled: false keycloak_quarkus_health_enabled: true diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 37c873e..5760c7d 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -308,6 +308,10 @@ argument_specs: default: false type: "bool" description: "By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled." + keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: + default: true + type: "bool" + description: "If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy" downstream: options: rhbk_version: diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 8ea545d..9d6aaaa 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -55,8 +55,7 @@ cache-stack=tcp # Proxy proxy={{ keycloak_quarkus_proxy_mode }} {% endif %} -# Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy -#spi-sticky-session-encoder-infinispan-should-attach-route=false +spi-sticky-session-encoder-infinispan-should-attach-route={{ keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route | d(true) | lower }} # Transaction transaction-xa-enabled={{ keycloak_quarkus_transaction_xa_enabled | lower }} From 4adab64dc0ca52e36e5963b013de330331d7aedc Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 22 Jan 2024 09:28:00 +0100 Subject: [PATCH 158/376] #158: support for TCPPING --- roles/keycloak_quarkus/README.md | 3 ++- roles/keycloak_quarkus/defaults/main.yml | 3 ++- roles/keycloak_quarkus/handlers/main.yml | 4 ++++ roles/keycloak_quarkus/meta/argument_specs.yml | 6 +++++- roles/keycloak_quarkus/tasks/main.yml | 16 ++++++++++++++++ roles/keycloak_quarkus/tasks/rebuild_config.yml | 7 +++++++ .../templates/keycloak.service.j2 | 2 +- 7 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 roles/keycloak_quarkus/tasks/rebuild_config.yml diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index cd720a5..a554254 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -19,6 +19,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| |`keycloak_quarkus_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` | +|`keycloak_quarkus_ha_discovery`| Discovery protocol for HA cluster members | `TCPPING` | |`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` | |`keycloak_quarkus_admin_user`| Administration console user account | `admin` | |`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | @@ -28,7 +29,7 @@ Role Defaults |`keycloak_quarkus_http_port`| HTTP listening port | `8080` | |`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` | -|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7600` | +|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7800` | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` | |`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index da42960..07d83b7 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -37,7 +37,7 @@ keycloak_quarkus_http_enabled: true keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 keycloak_quarkus_ajp_port: 8009 -keycloak_quarkus_jgroups_port: 7600 +keycloak_quarkus_jgroups_port: 7800 keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m" ### TLS/HTTPS configuration @@ -55,6 +55,7 @@ keycloak_quarkus_trust_store_password: '' ### Enable configuration for database backend, clustering and remote caches on infinispan keycloak_quarkus_ha_enabled: false +keycloak_quarkus_ha_discovery: "TCPPING" ### Enable database configuration, must be enabled when HA is configured keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False }}" diff --git a/roles/keycloak_quarkus/handlers/main.yml b/roles/keycloak_quarkus/handlers/main.yml index 00cab00..6cbe276 100644 --- a/roles/keycloak_quarkus/handlers/main.yml +++ b/roles/keycloak_quarkus/handlers/main.yml @@ -1,4 +1,8 @@ --- +# handler should be invoked anytime a [build configuration](https://www.keycloak.org/server/all-config?f=build) changes +- name: "Rebuild {{ keycloak.service_name }} config" + ansible.builtin.include_tasks: rebuild_config.yml + listen: "rebuild keycloak config" - name: "Restart {{ keycloak.service_name }}" ansible.builtin.include_tasks: restart.yml listen: "restart keycloak" \ No newline at end of file diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 37c873e..1d371ed 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -168,7 +168,7 @@ argument_specs: type: "int" keycloak_quarkus_jgroups_port: # line 32 of defaults/main.yml - default: 7600 + default: 7800 description: "jgroups cluster tcp port" type: "int" keycloak_quarkus_java_opts: @@ -181,6 +181,10 @@ argument_specs: default: false description: "Enable auto configuration for database backend, clustering and remote caches on infinispan" type: "bool" + keycloak_quarkus_ha_discovery: + default: "TCPPING" + description: "Discovery protocol for HA cluster members" + type: "str" keycloak_quarkus_db_enabled: # line 38 of defaults/main.yml default: "{{ True if keycloak_quarkus_ha_enabled else False }}" diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 394cf3b..c65ab59 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -30,6 +30,7 @@ mode: 0644 become: true notify: + - rebuild keycloak config - restart keycloak - name: "Configure quarkus config for keycloak service" @@ -43,6 +44,20 @@ notify: - restart keycloak +- name: Create tcpping cluster node list + ansible.builtin.set_fact: + keycloak_quarkus_cluster_nodes: > + {{ keycloak_quarkus_cluster_nodes | default([]) + [ + { + "name": item, + "address": 'jgroups-' + item, + "inventory_host": hostvars[item].ansible_default_ipv4.address | default(item) + '[' + (keycloak_quarkus_jgroups_port | string) + ']', + "value": hostvars[item].ansible_default_ipv4.address | default(item) + } + ] }} + loop: "{{ ansible_play_batch }}" + when: keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING' + - name: "Configure infinispan config for keycloak service" ansible.builtin.template: src: cache-ispn.xml @@ -52,6 +67,7 @@ mode: 0644 become: true notify: + - rebuild keycloak config - restart keycloak - name: Ensure logdirectory exists diff --git a/roles/keycloak_quarkus/tasks/rebuild_config.yml b/roles/keycloak_quarkus/tasks/rebuild_config.yml new file mode 100644 index 0000000..5a715c6 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/rebuild_config.yml @@ -0,0 +1,7 @@ +--- +# cf. https://www.keycloak.org/server/configuration#_optimize_the_keycloak_startup +- name: "Rebuild {{ keycloak.service_name }} config" + ansible.builtin.shell: | + {{ keycloak.home }}/bin/kc.sh build + become: true + changed_when: true diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index a529c5b..5b90986 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -10,7 +10,7 @@ PIDFile={{ keycloak_quarkus_service_pidfile }} {% if keycloak_quarkus_start_dev %} ExecStart={{ keycloak.home }}/bin/kc.sh start-dev {% else %} -ExecStart={{ keycloak.home }}/bin/kc.sh start --log={{ keycloak_quarkus_log }} +ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized {% endif %} User={{ keycloak.service_user }} Group={{ keycloak.service_group }} From df81dc54971fbcab930431fe4312f10569bfd14b Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 22 Jan 2024 11:15:04 +0100 Subject: [PATCH 159/376] #158: move TCPPING config to ispn config file --- .../keycloak_quarkus/templates/cache-ispn.xml | 20 +++++++++++++++++-- .../templates/keycloak.conf.j2 | 4 +++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/templates/cache-ispn.xml b/roles/keycloak_quarkus/templates/cache-ispn.xml index 20a1af7..67514d3 100644 --- a/roles/keycloak_quarkus/templates/cache-ispn.xml +++ b/roles/keycloak_quarkus/templates/cache-ispn.xml @@ -1,4 +1,4 @@ -# {{ ansible_managed }} + + + + +{% endif %} + - + diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 8ea545d..81acce9 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -48,7 +48,9 @@ hostname-strict-backchannel={{ keycloak_quarkus_hostname_strict_backchannel | lo {% if keycloak_quarkus_ha_enabled %} cache=ispn cache-config-file=cache-ispn.xml -cache-stack=tcp +{% if keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING' %} +# cache-stack=tcp # configured directly in `cache-ispn.xml` +{% endif %} {% endif %} {% if keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %} From f7bef0a956dbb5fefa1dea2b27888e3d306c852e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 22 Feb 2024 16:28:24 +0100 Subject: [PATCH 160/376] set enable-recovery when xa transactions are enabled --- roles/keycloak_quarkus/templates/quarkus.properties.j2 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/templates/quarkus.properties.j2 b/roles/keycloak_quarkus/templates/quarkus.properties.j2 index f8502f2..7ef1db7 100644 --- a/roles/keycloak_quarkus/templates/quarkus.properties.j2 +++ b/roles/keycloak_quarkus/templates/quarkus.properties.j2 @@ -23,4 +23,7 @@ quarkus.infinispan-client.trust-store-type=jks {% endif %} quarkus.log.file.rotation.max-file-size={{ keycloak_quarkus_log_max_file_size }} quarkus.log.file.rotation.max-backup-index={{ keycloak_quarkus_log_max_backup_index }} -quarkus.log.file.rotation.file-suffix={{ keycloak_quarkus_log_file_suffix }} \ No newline at end of file +quarkus.log.file.rotation.file-suffix={{ keycloak_quarkus_log_file_suffix }} +{% if keycloak_quarkus_db_enabled %} +quarkus.transaction-manager.enable-recovery=true +{% endif %} From d4fb20b230797a53f54518dca78db5dec1c700d7 Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Thu, 22 Feb 2024 17:10:22 +0100 Subject: [PATCH 161/376] Update Keycloak to version 23.0.7 --- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 2dd7ca0..7c01eae 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `23.0.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `23.0.7` | * Service configuration @@ -92,7 +92,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:---------| |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| -|`keycloak_quarkus_version`| keycloak.org package version | `23.0.1` | +|`keycloak_quarkus_version`| keycloak.org package version | `23.0.7` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 612dd65..f5cdb82 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 23.0.1 +keycloak_quarkus_version: 23.0.7 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" From b3ca517583488d8be5d1fa0f20009f3a71e039ce Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Thu, 22 Feb 2024 11:14:54 +0100 Subject: [PATCH 162/376] molecule: adapt sudo setup to work when ansible is not connecting as root on the target --- molecule/default/prepare.yml | 4 +++- molecule/prepare.yml | 22 ++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index 437f3e2..43e4e54 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -5,12 +5,14 @@ - name: Install sudo ansible.builtin.yum: name: - - sudo - java-1.8.0-openjdk state: present - name: Prepare hosts: all + gather_facts: yes + vars: + sudo_pkg_name: sudo tasks: - name: "Run preparation common to all scenario" ansible.builtin.include_tasks: ../prepare.yml diff --git a/molecule/prepare.yml b/molecule/prepare.yml index a927ba0..d01d6fd 100644 --- a/molecule/prepare.yml +++ b/molecule/prepare.yml @@ -3,9 +3,27 @@ ansible.builtin.debug: msg: "Ansible version is {{ ansible_version.full }}" -- name: Install sudo + +- name: "Ensure {{ sudo_pkg_name }} is installed (if user is root)." ansible.builtin.yum: - name: + name: "{{ sudo_pkg_name }}" + when: + - ansible_user_id == 'root' + + +- name: Gather the package facts + ansible.builtin.package_facts: + manager: auto + +- name: "Check if {{ sudo_pkg_name }} is installed." + ansible.builtin.assert: + that: + - sudo_pkg_name in ansible_facts.packages + +- name: Install sudo + become: yes + ansible.builtin.yum: + name: - sudo - iproute state: present From 7324f48e8dea2b7fba0feac3381c81351f2cafc6 Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Thu, 22 Feb 2024 11:22:32 +0100 Subject: [PATCH 163/376] molecule: cleanup prepare to use one play --- molecule/default/prepare.yml | 18 +++++----- molecule/default/verify.yml | 59 +++++++++++++++++--------------- molecule/overridexml/prepare.yml | 3 ++ 3 files changed, 43 insertions(+), 37 deletions(-) diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index 43e4e54..da1ab18 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -1,13 +1,4 @@ --- -- name: Prepare - hosts: all - tasks: - - name: Install sudo - ansible.builtin.yum: - name: - - java-1.8.0-openjdk - state: present - - name: Prepare hosts: all gather_facts: yes @@ -20,3 +11,12 @@ assets: - "{{ assets_server }}/sso/7.6.0/rh-sso-7.6.0-server-dist.zip" - "{{ assets_server }}/sso/7.6.1/rh-sso-7.6.1-patch.zip" + + - name: Install JDK8 + become: yes + ansible.builtin.yum: + name: + - java-1.8.0-openjdk + state: present + + diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index ba0e01f..39e94c5 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -56,31 +56,34 @@ ansible.builtin.assert: that: - (keycloak_query_clients.json | selectattr('clientId','equalto','TestClient') | first)["attributes"]["post.logout.redirect.uris"] == '/public/logout' - - name: Check log folder - ansible.builtin.stat: - path: "/tmp/keycloak" - register: keycloak_log_folder - - name: Check that keycloak log folder exists and is a link - ansible.builtin.assert: - that: - - keycloak_log_folder.stat.exists - - not keycloak_log_folder.stat.isdir - - keycloak_log_folder.stat.islnk - - name: Check log file - ansible.builtin.stat: - path: "/tmp/keycloak/server.log" - register: keycloak_log_file - - name: Check if keycloak file exists - ansible.builtin.assert: - that: - - keycloak_log_file.stat.exists - - not keycloak_log_file.stat.isdir - - name: Check default log folder - ansible.builtin.stat: - path: "/var/log/keycloak" - register: keycloak_default_log_folder - failed_when: false - - name: Check that default keycloak log folder doesn't exist - ansible.builtin.assert: - that: - - not keycloak_default_log_folder.stat.exists + - name: "Privilege escalation as some files/folders may requires it" + become: yes + block: + - name: Check log folder + ansible.builtin.stat: + path: "/tmp/keycloak" + register: keycloak_log_folder + - name: Check that keycloak log folder exists and is a link + ansible.builtin.assert: + that: + - keycloak_log_folder.stat.exists + - not keycloak_log_folder.stat.isdir + - keycloak_log_folder.stat.islnk + - name: Check log file + ansible.builtin.stat: + path: "/tmp/keycloak/server.log" + register: keycloak_log_file + - name: Check if keycloak file exists + ansible.builtin.assert: + that: + - keycloak_log_file.stat.exists + - not keycloak_log_file.stat.isdir + - name: Check default log folder + ansible.builtin.stat: + path: "/var/log/keycloak" + register: keycloak_default_log_folder + failed_when: false + - name: Check that default keycloak log folder doesn't exist + ansible.builtin.assert: + that: + - not keycloak_default_log_folder.stat.exists diff --git a/molecule/overridexml/prepare.yml b/molecule/overridexml/prepare.yml index f9b2406..26245be 100644 --- a/molecule/overridexml/prepare.yml +++ b/molecule/overridexml/prepare.yml @@ -1,6 +1,9 @@ --- - name: Prepare hosts: all + gather_facts: yes + vars: + sudo_pkg_name: sudo tasks: - name: "Run preparation common to all scenario" ansible.builtin.include_tasks: ../prepare.yml From 5bd39a0d0eb6a21151b81d549c658a7953c97154 Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Thu, 22 Feb 2024 12:17:32 +0100 Subject: [PATCH 164/376] molecule: use block to skip assets download entirely if needed --- molecule/prepare.yml | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/molecule/prepare.yml b/molecule/prepare.yml index d01d6fd..9d39694 100644 --- a/molecule/prepare.yml +++ b/molecule/prepare.yml @@ -32,22 +32,21 @@ ansible.builtin.set_fact: assets_server: "{{ lookup('env','MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" -- name: "Set offline when assets server from env is defined" - ansible.builtin.set_fact: - sso_offline_install: True +- name: "Download artefacts only if assets_server is set" when: - assets_server is defined - assets_server | length > 0 + block: + - name: "Set offline when assets server from env is defined" + ansible.builtin.set_fact: + sso_offline_install: True -- name: "Download and deploy zips from {{ assets_server }}" - ansible.builtin.get_url: - url: "{{ asset }}" - dest: "{{ lookup('env', 'PWD') }}" - validate_certs: no - delegate_to: localhost - loop: "{{ assets }}" - loop_control: - loop_var: asset - when: - - assets_server is defined - - assets_server | length > 0 + - name: "Download and deploy zips from {{ assets_server }}" + ansible.builtin.get_url: + url: "{{ asset }}" + dest: "{{ lookup('env', 'PWD') }}" + validate_certs: no + delegate_to: localhost + loop: "{{ assets }}" + loop_control: + loop_var: asset From 167bf512c5ce2c01dcef0a04a94c7f483eb7671a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 27 Feb 2024 17:17:14 +0100 Subject: [PATCH 165/376] fix typo in variable name --- roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index b028085..a665ec8 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -1,6 +1,6 @@ # {{ ansible_managed }} KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' -PATH={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -JAVA_HOME={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }} -JAVA_OPTS_APPEND={{ keycloak_quarkus_java_opts }} \ No newline at end of file +PATH={{ keycloak_quarkus_java_home | default(keycloak_rpm_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_rpm_java_home, true) }} +JAVA_OPTS_APPEND={{ keycloak_quarkus_java_opts }} From 7f021a849efc7932960aa7f944bcd2c528c5305c Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 27 Feb 2024 17:17:24 +0100 Subject: [PATCH 166/376] Linter --- molecule/https_revproxy/prepare.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/molecule/https_revproxy/prepare.yml b/molecule/https_revproxy/prepare.yml index a641257..44018be 100644 --- a/molecule/https_revproxy/prepare.yml +++ b/molecule/https_revproxy/prepare.yml @@ -33,6 +33,7 @@ ansible.builtin.file: path: /etc/nginx/tls state: directory + mode: 0755 - name: Copy certificates ansible.builtin.copy: src: "{{ item.name }}" From d97ddbde3c3a67d790469c67116a4b141a9b71b9 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 27 Feb 2024 19:27:07 +0100 Subject: [PATCH 167/376] add test --- molecule/quarkus-devmode/converge.yml | 1 + molecule/quarkus-devmode/prepare.yml | 11 ++++++++++- molecule/quarkus-devmode/verify.yml | 8 ++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/molecule/quarkus-devmode/converge.yml b/molecule/quarkus-devmode/converge.yml index 6cbe7d8..2a45189 100644 --- a/molecule/quarkus-devmode/converge.yml +++ b/molecule/quarkus-devmode/converge.yml @@ -9,6 +9,7 @@ keycloak_quarkus_frontend_url: 'http://localhost:8080/' keycloak_quarkus_start_dev: True keycloak_quarkus_proxy_mode: none + keycloak_quarkus_java_home: /opt/openjdk/ roles: - role: keycloak_quarkus - role: keycloak_realm diff --git a/molecule/quarkus-devmode/prepare.yml b/molecule/quarkus-devmode/prepare.yml index 09cbda3..88c2fb3 100644 --- a/molecule/quarkus-devmode/prepare.yml +++ b/molecule/quarkus-devmode/prepare.yml @@ -4,9 +4,18 @@ tasks: - name: Install sudo ansible.builtin.yum: - name: sudo + name: + - sudo + - java-17-openjdk-headless state: present + - name: Link default logs directory + ansible.builtin.file: + state: link + src: /usr/lib/jvm/jre-17-openjdk + dest: /opt/openjdk + force: true + - name: "Display hera_home if defined." ansible.builtin.set_fact: hera_home: "{{ lookup('env', 'HERA_HOME') }}" diff --git a/molecule/quarkus-devmode/verify.yml b/molecule/quarkus-devmode/verify.yml index ebb6047..b808ece 100644 --- a/molecule/quarkus-devmode/verify.yml +++ b/molecule/quarkus-devmode/verify.yml @@ -11,6 +11,14 @@ - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" + - name: Verify we are running on requested JAVA_HOME # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + ps -ef | grep '/opt/openjdk' | grep -v grep + args: + executable: /bin/bash + changed_when: False + - name: Set internal envvar ansible.builtin.set_fact: hera_home: "{{ lookup('env', 'HERA_HOME') }}" From 1e1665adb05d313ccc4f6218650515daf61a8095 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 28 Feb 2024 15:58:33 +0000 Subject: [PATCH 168/376] Update changelog for release 2.1.0 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 33 ++++++++++++++++++++++++++++----- changelogs/changelog.yaml | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c3a46da..15c2fbf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,11 +1,36 @@ -============================================ -middleware_automation.keycloak Release Notes -============================================ +============================================= +middleware\_automation.keycloak Release Notes +============================================= .. contents:: Topics This changelog describes changes after version 0.2.6. +v2.1.0 +====== + +Major Changes +------------- + +- Implement infinispan TCPPING discovery protocol `#159 `_ + +Minor Changes +------------- + +- Set enable-recovery when xa transactions are enabled `#167 `_ +- keycloak_quarkus: Allow configuring log rotate options in quarkus configuration `#161 `_ +- keycloak_quarkus: ``sticky-session`` for infinispan routes `#163 `_ + +Breaking Changes / Porting Guide +-------------------------------- + +- keycloak_quarkus: renamed infinispan host list configuration `#157 `_ + +Bugfixes +-------- + +- keycloak_quarkus: fix custom JAVA_HOME parameter name `#171 `_ + v2.0.2 ====== @@ -269,7 +294,6 @@ Release Summary Minor enhancements, bug and documentation fixes. - Major Changes ------------- @@ -287,4 +311,3 @@ Release Summary --------------- This is the first stable release of the ``middleware_automation.keycloak`` collection. - diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 7d684cd..dd44253 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -386,3 +386,36 @@ releases: - 152.yaml - 154.yaml release_date: '2024-01-17' + 2.1.0: + changes: + breaking_changes: + - 'keycloak_quarkus: renamed infinispan host list configuration `#157 `_ + + ' + bugfixes: + - 'keycloak_quarkus: fix custom JAVA_HOME parameter name `#171 `_ + + ' + major_changes: + - 'Implement infinispan TCPPING discovery protocol `#159 `_ + + ' + minor_changes: + - 'Set enable-recovery when xa transactions are enabled `#167 `_ + + ' + - 'keycloak_quarkus: Allow configuring log rotate options in quarkus configuration + `#161 `_ + + ' + - 'keycloak_quarkus: ``sticky-session`` for infinispan routes `#163 `_ + + ' + fragments: + - 157.yaml + - 159.yaml + - 161.yaml + - 163.yaml + - 167.yaml + - 171.yaml + release_date: '2024-02-28' From 6541b5e386796777f33eba4b8cce007ec4662175 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 28 Feb 2024 15:58:47 +0000 Subject: [PATCH 169/376] Bump version to 2.1.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 6a1d110..dd55345 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.1.0" +version: "2.1.1" readme: README.md authors: - Romain Pelisse From d74820190f5231a0e33fcb31af9acb2e61618e8a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 28 Feb 2024 17:10:02 +0100 Subject: [PATCH 170/376] ci: rename keycloak_quarkus infinispan jinja2 template --- roles/keycloak_quarkus/tasks/main.yml | 2 +- .../templates/{cache-ispn.xml => cache-ispn.xml.j2} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename roles/keycloak_quarkus/templates/{cache-ispn.xml => cache-ispn.xml.j2} (100%) diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index c65ab59..4e55961 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -60,7 +60,7 @@ - name: "Configure infinispan config for keycloak service" ansible.builtin.template: - src: cache-ispn.xml + src: cache-ispn.xml.j2 dest: "{{ keycloak.home }}/conf/cache-ispn.xml" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" diff --git a/roles/keycloak_quarkus/templates/cache-ispn.xml b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 similarity index 100% rename from roles/keycloak_quarkus/templates/cache-ispn.xml rename to roles/keycloak_quarkus/templates/cache-ispn.xml.j2 From a59a1fb8dd16ca33a7c87418f158faf9fc4cef7f Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Mon, 4 Mar 2024 21:13:06 +0100 Subject: [PATCH 171/376] Rework Molecule prepare phase to install sudo only if root on target --- molecule/prepare.yml | 13 +++++++++---- molecule/quarkus-devmode/prepare.yml | 12 ++++++------ molecule/quarkus/prepare.yml | 12 ++++-------- molecule/quarkus/verify.yml | 4 +++- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/molecule/prepare.yml b/molecule/prepare.yml index 9d39694..f122f9d 100644 --- a/molecule/prepare.yml +++ b/molecule/prepare.yml @@ -3,28 +3,31 @@ ansible.builtin.debug: msg: "Ansible version is {{ ansible_version.full }}" +- name: "Set package name for sudo" + ansible.builtin.set_fact: + sudo_pkg_name: sudo - name: "Ensure {{ sudo_pkg_name }} is installed (if user is root)." ansible.builtin.yum: name: "{{ sudo_pkg_name }}" + state: present when: - ansible_user_id == 'root' - - name: Gather the package facts ansible.builtin.package_facts: manager: auto -- name: "Check if {{ sudo_pkg_name }} is installed." +- name: "Check if sudo is installed." ansible.builtin.assert: that: - sudo_pkg_name in ansible_facts.packages + fail_msg: "sudo is not installed on target system" -- name: Install sudo +- name: "Install iproute" become: yes ansible.builtin.yum: name: - - sudo - iproute state: present @@ -36,6 +39,8 @@ when: - assets_server is defined - assets_server | length > 0 + - assets is defined + - assets | length > 0 block: - name: "Set offline when assets server from env is defined" ansible.builtin.set_fact: diff --git a/molecule/quarkus-devmode/prepare.yml b/molecule/quarkus-devmode/prepare.yml index 88c2fb3..313adb8 100644 --- a/molecule/quarkus-devmode/prepare.yml +++ b/molecule/quarkus-devmode/prepare.yml @@ -2,20 +2,20 @@ - name: Prepare hosts: all tasks: - - name: Install sudo + - name: "Ensure common prepare phase are set." + ansible.builtin.include_tasks: ../prepare.yml + + - name: Install JDK17 + become: yes ansible.builtin.yum: name: - - sudo - java-17-openjdk-headless state: present - name: Link default logs directory + become: yes ansible.builtin.file: state: link src: /usr/lib/jvm/jre-17-openjdk dest: /opt/openjdk force: true - - - name: "Display hera_home if defined." - ansible.builtin.set_fact: - hera_home: "{{ lookup('env', 'HERA_HOME') }}" diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 13d85a8..c7ba481 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -2,14 +2,8 @@ - name: Prepare hosts: all tasks: - - name: Install sudo - ansible.builtin.yum: - name: sudo - state: present - - - name: "Display hera_home if defined." - ansible.builtin.set_fact: - hera_home: "{{ lookup('env', 'HERA_HOME') }}" + - name: "Ensure common prepare phase are set." + ansible.builtin.include_tasks: ../prepare.yml - name: Create certificate request ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' @@ -17,12 +11,14 @@ changed_when: False - name: Create conf directory # risky-file-permissions in test user account does not exist yet + become: yes ansible.builtin.file: state: directory path: "/opt/keycloak/certs/" mode: 0755 - name: Copy certificates + become: yes ansible.builtin.copy: src: "{{ item }}" dest: "/opt/keycloak/certs/{{ item }}" diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 2d75c32..a58a13f 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -49,8 +49,9 @@ - keycloak_log_folder.stat.exists - not keycloak_log_folder.stat.isdir - keycloak_log_folder.stat.islnk - + - name: Check log file + become: yes ansible.builtin.stat: path: "/tmp/keycloak/keycloak.log" register: keycloak_log_file @@ -62,6 +63,7 @@ - not keycloak_log_file.stat.isdir - name: Check default log folder + become: yes ansible.builtin.stat: path: "/var/log/keycloak" register: keycloak_default_log_folder From a97c349f41c8429886b41c7f609d0f96ccce8861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gro=C3=9Fewinkelmann?= Date: Wed, 13 Mar 2024 00:12:15 +0100 Subject: [PATCH 172/376] Utilize comment filter for {{ ansible_maanged }} annotations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Großewinkelmann --- molecule/overridexml/templates/custom.xml.j2 | 2 +- roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/15.0.8/standalone.xml.j2 | 2 +- roles/keycloak/templates/keycloak-service.sh.j2 | 2 +- roles/keycloak/templates/keycloak-sysconfig.j2 | 2 +- roles/keycloak/templates/keycloak.service.j2 | 2 +- roles/keycloak/templates/standalone-ha.xml.j2 | 2 +- roles/keycloak/templates/standalone-infinispan.xml.j2 | 2 +- roles/keycloak/templates/standalone.xml.j2 | 2 +- roles/keycloak_quarkus/templates/cache-ispn.xml.j2 | 2 +- roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 | 2 +- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 2 +- roles/keycloak_quarkus/templates/keycloak.service.j2 | 2 +- roles/keycloak_quarkus/templates/quarkus.properties.j2 | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/molecule/overridexml/templates/custom.xml.j2 b/molecule/overridexml/templates/custom.xml.j2 index 8686d77..66c5852 100644 --- a/molecule/overridexml/templates/custom.xml.j2 +++ b/molecule/overridexml/templates/custom.xml.j2 @@ -1,5 +1,5 @@ - +{{ ansible_managed | comment('xml') }} diff --git a/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 index 2d84f3f..25d6cb0 100644 --- a/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/15.0.8/standalone-infinispan.xml.j2 @@ -1,5 +1,5 @@ - +{{ ansible_managed | comment('xml') }} diff --git a/roles/keycloak/templates/15.0.8/standalone.xml.j2 b/roles/keycloak/templates/15.0.8/standalone.xml.j2 index de175f2..01c317b 100644 --- a/roles/keycloak/templates/15.0.8/standalone.xml.j2 +++ b/roles/keycloak/templates/15.0.8/standalone.xml.j2 @@ -1,5 +1,5 @@ - +{{ ansible_managed | comment('xml') }} diff --git a/roles/keycloak/templates/keycloak-service.sh.j2 b/roles/keycloak/templates/keycloak-service.sh.j2 index 577959e..98efb34 100755 --- a/roles/keycloak/templates/keycloak-service.sh.j2 +++ b/roles/keycloak/templates/keycloak-service.sh.j2 @@ -1,5 +1,5 @@ #!/bin/bash -eu -# {{ ansible_managed }} +{{ ansible_managed | comment }} set +u -o pipefail diff --git a/roles/keycloak/templates/keycloak-sysconfig.j2 b/roles/keycloak/templates/keycloak-sysconfig.j2 index 86a96d6..4c38522 100644 --- a/roles/keycloak/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak/templates/keycloak-sysconfig.j2 @@ -1,4 +1,4 @@ -# {{ ansible_managed }} +{{ ansible_managed | comment }} JAVA_OPTS='{{ keycloak_java_opts }}' JAVA_HOME={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }} JBOSS_HOME={{ keycloak.home }} diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index 15a6ddf..eea3ba1 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -1,4 +1,4 @@ -# {{ ansible_managed }} +{{ ansible_managed | comment }} [Unit] Description={{ keycloak.service_name }} Server After=network.target diff --git a/roles/keycloak/templates/standalone-ha.xml.j2 b/roles/keycloak/templates/standalone-ha.xml.j2 index 99399f3..d027c35 100644 --- a/roles/keycloak/templates/standalone-ha.xml.j2 +++ b/roles/keycloak/templates/standalone-ha.xml.j2 @@ -1,5 +1,5 @@ - +{{ ansible_managed | comment('xml') }} diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 index 0b0c8af..18e5a7c 100644 --- a/roles/keycloak/templates/standalone-infinispan.xml.j2 +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -1,5 +1,5 @@ - +{{ ansible_managed | comment('xml') }} diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 index 72fe4d6..5ee20ed 100644 --- a/roles/keycloak/templates/standalone.xml.j2 +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -1,5 +1,5 @@ - +{{ ansible_managed | comment('xml') }} diff --git a/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 index 67514d3..fb11cda 100644 --- a/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 +++ b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 @@ -1,4 +1,4 @@ - +{{ ansible_managed | comment('xml') }} @@ -481,7 +481,7 @@ default - + @@ -520,7 +520,8 @@ - + + @@ -549,7 +550,9 @@ + + diff --git a/molecule/overridexml/verify.yml b/molecule/overridexml/verify.yml index ef973cd..b267fa1 100644 --- a/molecule/overridexml/verify.yml +++ b/molecule/overridexml/verify.yml @@ -1,6 +1,10 @@ --- - name: Verify hosts: all + vars: + keycloak_uri: "http://localhost:8081" + keycloak_management_port: "http://localhost:19990" + keycloak_admin_password: "remembertochangeme" tasks: - name: Populate service facts ansible.builtin.service_facts: @@ -9,3 +13,20 @@ that: - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" + - name: Verify we are running on requested jvm # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + ps -ef | grep '/etc/alternatives/jre_1.8.0/' | grep -v grep + args: + executable: /bin/bash + changed_when: no + - name: Verify token api call + ansible.builtin.uri: + url: "{{ keycloak_uri }}/auth/realms/master/protocol/openid-connect/token" + method: POST + body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password" + validate_certs: no + register: keycloak_auth_response + until: keycloak_auth_response.status == 200 + retries: 2 + delay: 2 From b9d9874a00f522709b289ed26b5f8f13d14d07ae Mon Sep 17 00:00:00 2001 From: Malik Kennedy Date: Sat, 16 Mar 2024 18:17:20 +0000 Subject: [PATCH 177/376] feat: ubuntu compatibility --- bindep.txt | 11 ++++---- molecule/default/prepare.yml | 9 ++++++- molecule/quarkus-devmode/prepare.yml | 24 +++++++++++++++++ molecule/quarkus/prepare.yml | 2 +- roles/keycloak/README.md | 1 + roles/keycloak/defaults/main.yml | 4 ++- roles/keycloak/meta/argument_specs.yml | 5 ++++ roles/keycloak/tasks/debian.yml | 6 +++++ roles/keycloak/tasks/fastpackages.yml | 15 ++++++++++- roles/keycloak/tasks/iptables.yml | 23 ++++++++++++++++ roles/keycloak/tasks/main.yml | 15 ++++++++--- roles/keycloak/tasks/prereqs.yml | 6 ++--- roles/keycloak/tasks/redhat.yml | 6 +++++ roles/keycloak/tasks/systemd.yml | 25 +++++++++++++++++ roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/tasks/debian.yml | 6 +++++ roles/keycloak_quarkus/tasks/fastpackages.yml | 15 ++++++++++- roles/keycloak_quarkus/tasks/iptables.yml | 20 ++++++++++++++ roles/keycloak_quarkus/tasks/main.yml | 14 +++++++--- roles/keycloak_quarkus/tasks/prereqs.yml | 6 ++--- roles/keycloak_quarkus/tasks/redhat.yml | 6 +++++ roles/keycloak_quarkus/tasks/systemd.yml | 27 ++++++++++++++++++- 22 files changed, 222 insertions(+), 26 deletions(-) create mode 100644 roles/keycloak/tasks/debian.yml create mode 100644 roles/keycloak/tasks/iptables.yml create mode 100644 roles/keycloak/tasks/redhat.yml create mode 100644 roles/keycloak_quarkus/tasks/debian.yml create mode 100644 roles/keycloak_quarkus/tasks/iptables.yml create mode 100644 roles/keycloak_quarkus/tasks/redhat.yml diff --git a/bindep.txt b/bindep.txt index 840876b..0014f47 100644 --- a/bindep.txt +++ b/bindep.txt @@ -1,8 +1,9 @@ +python3-dev [compile platform:dpkg] python3-devel [compile platform:rpm] python39-devel [compile platform:centos-8 platform:rhel-8] -git-lfs [platform:rpm] -python3-netaddr [platform:rpm] -python3-lxml [platform:rpm] -python3-jmespath [platform:rpm] -python3-requests [platform:rpm] +git-lfs [platform:rpm platform:dpkg] +python3-netaddr [platform:rpm platform:dpkg] +python3-lxml [platform:rpm platform:dpkg] +python3-jmespath [platform:rpm platform:dpkg] +python3-requests [platform:rpm platform:dpkg] diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index da1ab18..b707f6c 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -18,5 +18,12 @@ name: - java-1.8.0-openjdk state: present + when: ansible_facts['os_family'] == "RedHat" - + - name: Install JDK8 + become: yes + ansible.builtin.apt: + name: + - openjdk-8-jdk + state: present + when: ansible_facts['os_family'] == "Debian" diff --git a/molecule/quarkus-devmode/prepare.yml b/molecule/quarkus-devmode/prepare.yml index 88c2fb3..924aebc 100644 --- a/molecule/quarkus-devmode/prepare.yml +++ b/molecule/quarkus-devmode/prepare.yml @@ -2,19 +2,43 @@ - name: Prepare hosts: all tasks: + - name: Install sudo + ansible.builtin.apt: + name: + - sudo + - openjdk-17-jdk-headless + state: present + when: + - ansible_facts.os_family == 'Debian' + - name: Install sudo ansible.builtin.yum: name: - sudo - java-17-openjdk-headless state: present + when: + - ansible_facts.os_family == 'RedHat' + - name: Link default logs directory + ansible.builtin.file: + state: link + src: "{{ item }}" + dest: /opt/openjdk + force: true + with_fileglob: + - /usr/lib/jvm/java-17-openjdk* + when: + - ansible_facts.os_family == "Debian" + - name: Link default logs directory ansible.builtin.file: state: link src: /usr/lib/jvm/jre-17-openjdk dest: /opt/openjdk force: true + when: + - ansible_facts.os_family == "RedHat" - name: "Display hera_home if defined." ansible.builtin.set_fact: diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 13d85a8..568bfef 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -3,7 +3,7 @@ hosts: all tasks: - name: Install sudo - ansible.builtin.yum: + ansible.builtin.package: name: sudo state: present diff --git a/roles/keycloak/README.md b/roles/keycloak/README.md index c4dfedc..3d3b560 100644 --- a/roles/keycloak/README.md +++ b/roles/keycloak/README.md @@ -10,6 +10,7 @@ Requirements This role requires the `python3-netaddr` library installed on the controller node. * to install via yum/dnf: `dnf install python3-netaddr` +* to install via apt: `apt install python3-netaddr` * or via pip: `pip install netaddr==0.8.0` * or via the collection: `pip install -r requirements.txt` diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 7ffaec6..6658774 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -8,7 +8,8 @@ keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" keycloak_offline_install: false ### Install location and service settings -keycloak_jvm_package: java-1.8.0-openjdk-headless +keycloak_jvm_package: "{{ 'java-1.8.0-openjdk-headless' if ansible_facts.os_family == 'RedHat' else 'openjdk-8-jdk-headless' }}" + keycloak_java_home: keycloak_dest: /opt/keycloak keycloak_jboss_home: "{{ keycloak_installdir }}" @@ -33,6 +34,7 @@ keycloak_service_startlimitburst: "5" keycloak_service_restartsec: "10s" keycloak_configure_firewalld: false +keycloak_configure_iptables: false ### administrator console password keycloak_admin_password: '' diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index acdb309..ca1cb8b 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -11,6 +11,11 @@ argument_specs: default: "keycloak-legacy-{{ keycloak_version }}.zip" description: "keycloak install archive filename" type: "str" + keycloak_configure_iptables: + # line 33 of keycloak/defaults/main.yml + default: false + description: "Ensure iptables is running and configure keycloak ports" + type: "bool" keycloak_configure_firewalld: # line 33 of keycloak/defaults/main.yml default: false diff --git a/roles/keycloak/tasks/debian.yml b/roles/keycloak/tasks/debian.yml new file mode 100644 index 0000000..ffb1348 --- /dev/null +++ b/roles/keycloak/tasks/debian.yml @@ -0,0 +1,6 @@ +--- +- name: Include firewall config tasks + ansible.builtin.include_tasks: iptables.yml + when: keycloak_configure_iptables + tags: + - firewall diff --git a/roles/keycloak/tasks/fastpackages.yml b/roles/keycloak/tasks/fastpackages.yml index c9085f8..3b557ef 100644 --- a/roles/keycloak/tasks/fastpackages.yml +++ b/roles/keycloak/tasks/fastpackages.yml @@ -4,14 +4,27 @@ register: rpm_info changed_when: false failed_when: false + when: ansible_facts.os_family == "RedHat" - name: "Add missing packages to the yum install list" ansible.builtin.set_fact: packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" + when: ansible_facts.os_family == "RedHat" - name: "Install packages: {{ packages_to_install }}" become: true ansible.builtin.yum: name: "{{ packages_to_install }}" state: present - when: packages_to_install | default([]) | length > 0 + when: + - packages_to_install | default([]) | length > 0 + - ansible_facts.os_family == "RedHat" + +- name: "Install packages: {{ packages_list }}" + become: true + ansible.builtin.package: + name: "{{ packages_list }}" + state: present + when: + - packages_list | default([]) | length > 0 + - ansible_facts.os_family == "Debian" diff --git a/roles/keycloak/tasks/iptables.yml b/roles/keycloak/tasks/iptables.yml new file mode 100644 index 0000000..8ebc16e --- /dev/null +++ b/roles/keycloak/tasks/iptables.yml @@ -0,0 +1,23 @@ +--- +- name: Ensure required package iptables are installed + ansible.builtin.include_tasks: fastpackages.yml + vars: + packages_list: + - iptables + +- name: "Configure firewall ports for {{ keycloak.service_name }}" + become: true + ansible.builtin.iptables: + destination_port: "{{ item }}" + action: "insert" + rule_num: 6 # magic number I forget why + chain: "INPUT" + policy: "ACCEPT" + protocol: tcp + loop: + - "{{ keycloak_http_port }}" + - "{{ keycloak_https_port }}" + - "{{ keycloak_management_http_port }}" + - "{{ keycloak_management_https_port }}" + - "{{ keycloak_jgroups_port }}" + - "{{ keycloak_ajp_port }}" diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index cba503b..284900b 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -5,11 +5,17 @@ tags: - prereqs -- name: Include firewall config tasks - ansible.builtin.include_tasks: firewalld.yml - when: keycloak_configure_firewalld +- name: Debian specific tasks + ansible.builtin.include_tasks: debian.yml + when: ansible_facts.os_family == "Debian" tags: - - firewall + - unbound + +- name: RedHat specific tasks + ansible.builtin.include_tasks: redhat.yml + when: ansible_facts.os_family == "RedHat" + tags: + - unbound - name: Include install tasks ansible.builtin.include_tasks: install.yml @@ -26,6 +32,7 @@ when: - sso_apply_patches is defined and sso_apply_patches - sso_enable is defined and sso_enable + - ansible_facts.os_family == "RedHat" tags: - install - patch diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index aad814b..565931b 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -42,6 +42,6 @@ packages_list: - "{{ keycloak_jvm_package }}" - unzip - - procps-ng - - initscripts - - tzdata-java + - "{{ 'procps-ng' if ansible_facts.os_family == 'RedHat' else 'procps' }}" + - "{{ 'initscripts' if ansible_facts.os_family == 'RedHat' else 'apt' }}" + - "{{ 'tzdata-java' if ansible_facts.os_family == 'RedHat' else 'tzdata' }}" diff --git a/roles/keycloak/tasks/redhat.yml b/roles/keycloak/tasks/redhat.yml new file mode 100644 index 0000000..596834b --- /dev/null +++ b/roles/keycloak/tasks/redhat.yml @@ -0,0 +1,6 @@ +--- +- name: Include firewall config tasks + ansible.builtin.include_tasks: firewalld.yml + when: keycloak_configure_firewalld + tags: + - firewall diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index cd58345..cf84c32 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -10,9 +10,32 @@ notify: - restart keycloak +- name: Determine JAVA_HOME for selected JVM RPM + ansible.builtin.set_fact: + rpm_java_home: "/lib/jvm/java-{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" + when: + - ansible_facts.os_family == 'Debian' + - name: Determine JAVA_HOME for selected JVM RPM ansible.builtin.set_fact: rpm_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" + when: + - ansible_facts.os_family == 'RedHat' + +- name: "Configure sysconfig file for {{ keycloak.service_name }} service" + become: true + ansible.builtin.template: + src: keycloak-sysconfig.j2 + dest: /etc/default/keycloak + owner: root + group: root + mode: 0644 + vars: + keycloak_rpm_java_home: "{{ rpm_java_home }}" + when: + - ansible_facts.os_family == "Debian" + notify: + - restart keycloak - name: "Configure sysconfig file for {{ keycloak.service_name }} service" become: true @@ -24,6 +47,8 @@ mode: 0644 vars: keycloak_rpm_java_home: "{{ rpm_java_home }}" + when: + - ansible_facts.os_family == "RedHat" notify: - restart keycloak diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index f5cdb82..f2f07a5 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -9,7 +9,7 @@ keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_q keycloak_quarkus_offline_install: false ### Install location and service settings -keycloak_quarkus_jvm_package: java-17-openjdk-headless +keycloak_quarkus_jvm_package: "{{ 'java-17-openjdk-headless' if ansible_facts.os_family == 'RedHat' else 'openjdk-17-jdk-headless' }}" keycloak_quarkus_java_home: keycloak_quarkus_dest: /opt/keycloak keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" diff --git a/roles/keycloak_quarkus/tasks/debian.yml b/roles/keycloak_quarkus/tasks/debian.yml new file mode 100644 index 0000000..ffb1348 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/debian.yml @@ -0,0 +1,6 @@ +--- +- name: Include firewall config tasks + ansible.builtin.include_tasks: iptables.yml + when: keycloak_configure_iptables + tags: + - firewall diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml index c9085f8..3b557ef 100644 --- a/roles/keycloak_quarkus/tasks/fastpackages.yml +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -4,14 +4,27 @@ register: rpm_info changed_when: false failed_when: false + when: ansible_facts.os_family == "RedHat" - name: "Add missing packages to the yum install list" ansible.builtin.set_fact: packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" + when: ansible_facts.os_family == "RedHat" - name: "Install packages: {{ packages_to_install }}" become: true ansible.builtin.yum: name: "{{ packages_to_install }}" state: present - when: packages_to_install | default([]) | length > 0 + when: + - packages_to_install | default([]) | length > 0 + - ansible_facts.os_family == "RedHat" + +- name: "Install packages: {{ packages_list }}" + become: true + ansible.builtin.package: + name: "{{ packages_list }}" + state: present + when: + - packages_list | default([]) | length > 0 + - ansible_facts.os_family == "Debian" diff --git a/roles/keycloak_quarkus/tasks/iptables.yml b/roles/keycloak_quarkus/tasks/iptables.yml new file mode 100644 index 0000000..b487b89 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/iptables.yml @@ -0,0 +1,20 @@ +--- +- name: Ensure required package iptables are installed + ansible.builtin.include_tasks: fastpackages.yml + vars: + packages_list: + - iptables + +- name: "Configure firewall ports for {{ keycloak.service_name }}" + become: true + ansible.builtin.iptables: + destination_port: "{{ item }}" + action: "insert" + rule_num: 6 # magic number I forget why + chain: "INPUT" + policy: "ACCEPT" + protocol: tcp + loop: + - "{{ keycloak_quarkus_http_port }}" + - "{{ keycloak_quarkus_https_port }}" + - "{{ keycloak_quarkus_jgroups_port }}" diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 4e55961..72f4fdd 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -5,11 +5,17 @@ tags: - prereqs -- name: Include firewall config tasks - ansible.builtin.include_tasks: firewalld.yml - when: keycloak_quarkus_configure_firewalld +- name: Debian specific tasks + ansible.builtin.include_tasks: debian.yml + when: ansible_facts.os_family == "Debian" tags: - - firewall + - unbound + +- name: RedHat specific tasks + ansible.builtin.include_tasks: redhat.yml + when: ansible_facts.os_family == "RedHat" + tags: + - unbound - name: Include install tasks ansible.builtin.include_tasks: install.yml diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index ee2abca..252f75f 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -29,6 +29,6 @@ packages_list: - "{{ keycloak_quarkus_jvm_package }}" - unzip - - procps-ng - - initscripts - - tzdata-java + - "{{ 'procps-ng' if ansible_facts.os_family == 'RedHat' else 'procps' }}" + - "{{ 'initscripts' if ansible_facts.os_family == 'RedHat' else 'apt' }}" + - "{{ 'tzdata-java' if ansible_facts.os_family == 'RedHat' else 'tzdata' }}" diff --git a/roles/keycloak_quarkus/tasks/redhat.yml b/roles/keycloak_quarkus/tasks/redhat.yml new file mode 100644 index 0000000..093b930 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/redhat.yml @@ -0,0 +1,6 @@ +--- +- name: Include firewall config tasks + ansible.builtin.include_tasks: firewalld.yml + when: keycloak_quarkus_configure_firewalld + tags: + - firewall diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index 3d59b3f..65aeeb3 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -2,8 +2,31 @@ - name: Determine JAVA_HOME for selected JVM RPM ansible.builtin.set_fact: rpm_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" + when: + - ansible_facts.os_family == "RedHat" -- name: "Configure sysconfig file for keycloak service" +- name: Determine JAVA_HOME for selected JVM RPM + ansible.builtin.set_fact: + rpm_java_home: "/lib/jvm/java-{{ keycloak_quarkus_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" + when: + - ansible_facts.os_family == "Debian" + +- name: "Configure sysconfig file for {{ keycloak.service_name }} service" + become: true + ansible.builtin.template: + src: keycloak-sysconfig.j2 + dest: /etc/default/keycloak + owner: root + group: root + mode: 0644 + vars: + keycloak_rpm_java_home: "{{ rpm_java_home }}" + when: + - ansible_facts.os_family == "Debian" + notify: + - restart keycloak + +- name: "Configure sysconfig file for {{ keycloak.service_name }} service" become: true ansible.builtin.template: src: keycloak-sysconfig.j2 @@ -13,6 +36,8 @@ mode: 0644 vars: keycloak_rpm_java_home: "{{ rpm_java_home }}" + when: + - ansible_facts.os_family == "RedHat" notify: - restart keycloak From 56e4a43cf984558bc58bd84e184ec791b853a2d2 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 09:30:25 +0100 Subject: [PATCH 178/376] add keycloak_realm default to sub entities --- roles/keycloak_realm/tasks/main.yml | 6 +++--- roles/keycloak_realm/tasks/manage_client_roles.yml | 2 +- roles/keycloak_realm/tasks/manage_user_client_roles.yml | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index c1f66bc..016ab55 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -41,11 +41,11 @@ auth_realm: "{{ keycloak_auth_realm }}" auth_username: "{{ keycloak_admin_user }}" auth_password: "{{ keycloak_admin_password }}" - realm: "{{ item.realm }}" + realm: "{{ item.realm | default(keycloak_realm) }}" name: "{{ item.name }}" state: present provider_id: "{{ item.provider_id }}" - provider_type: "{{ item.provider_type | default(org.keycloak.storage.UserStorageProvider) }}" + provider_type: "{{ item.provider_type | default(org.keycloak.storage.UserStorageProvider) }}" config: "{{ item.config }}" mappers: "{{ item.mappers | default(omit) }}" no_log: "{{ keycloak_no_log | default('True') }}" @@ -71,7 +71,7 @@ auth_realm: "{{ keycloak_auth_realm }}" auth_username: "{{ keycloak_admin_user }}" auth_password: "{{ keycloak_admin_password }}" - realm: "{{ item.realm }}" + realm: "{{ item.realm | default(keycloak_realm) }}" default_roles: "{{ item.roles | default(omit) }}" client_id: "{{ item.client_id | default(omit) }}" id: "{{ item.id | default(omit) }}" diff --git a/roles/keycloak_realm/tasks/manage_client_roles.yml b/roles/keycloak_realm/tasks/manage_client_roles.yml index 4a261b1..fbb25ac 100644 --- a/roles/keycloak_realm/tasks/manage_client_roles.yml +++ b/roles/keycloak_realm/tasks/manage_client_roles.yml @@ -1,7 +1,7 @@ - name: Create client roles middleware_automation.keycloak.keycloak_role: name: "{{ item }}" - realm: "{{ client.realm }}" + realm: "{{ client.realm | default(keycloak_realm) }}" client_id: "{{ client.name }}" auth_client_id: "{{ keycloak_auth_client }}" auth_keycloak_url: "{{ keycloak_url }}{{ keycloak_context }}" diff --git a/roles/keycloak_realm/tasks/manage_user_client_roles.yml b/roles/keycloak_realm/tasks/manage_user_client_roles.yml index 85de09a..4311daa 100644 --- a/roles/keycloak_realm/tasks/manage_user_client_roles.yml +++ b/roles/keycloak_realm/tasks/manage_user_client_roles.yml @@ -1,7 +1,7 @@ --- - name: "Get Realm for role" ansible.builtin.uri: - url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm }}" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | default(keycloak_realm) }}" method: GET status_code: - 200 @@ -12,7 +12,7 @@ - name: Check if Mapping is available ansible.builtin.uri: - url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}/available" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | default(keycloak_realm) }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}/available" method: GET status_code: - 200 @@ -23,7 +23,7 @@ - name: "Create Role Mapping" ansible.builtin.uri: - url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | default(keycloak_realm) }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}" method: POST body: - id: "{{ item.id }}" From dd6171f0247733fc12534698111f78dbd8b206e7 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 10:19:08 +0100 Subject: [PATCH 179/376] Add ansible_family based vars loading --- roles/keycloak_quarkus/defaults/main.yml | 1 - roles/keycloak_quarkus/meta/main.yml | 6 ++++++ roles/keycloak_quarkus/tasks/prereqs.yml | 22 +++++++++++++++------- roles/keycloak_quarkus/vars/debian.yml | 11 +++++++++++ roles/keycloak_quarkus/vars/redhat.yml | 11 +++++++++++ 5 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 roles/keycloak_quarkus/vars/debian.yml create mode 100644 roles/keycloak_quarkus/vars/redhat.yml diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index f2f07a5..e630bd3 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -9,7 +9,6 @@ keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_q keycloak_quarkus_offline_install: false ### Install location and service settings -keycloak_quarkus_jvm_package: "{{ 'java-17-openjdk-headless' if ansible_facts.os_family == 'RedHat' else 'openjdk-17-jdk-headless' }}" keycloak_quarkus_java_home: keycloak_quarkus_dest: /opt/keycloak keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" diff --git a/roles/keycloak_quarkus/meta/main.yml b/roles/keycloak_quarkus/meta/main.yml index 8d7331d..0f82003 100644 --- a/roles/keycloak_quarkus/meta/main.yml +++ b/roles/keycloak_quarkus/meta/main.yml @@ -14,6 +14,11 @@ galaxy_info: - name: EL versions: - "8" + - "9" + - name: Fedora + - name: Debian + - name: Ubuntu + galaxy_tags: - keycloak @@ -25,3 +30,4 @@ galaxy_info: - identity - security - rhbk + - debian diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 252f75f..7a33a48 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -6,7 +6,7 @@ quiet: true fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass variable to a 12+ char long string" success_msg: "{{ 'Console administrator password OK' }}" - + - name: Validate relative path ansible.builtin.assert: that: @@ -23,12 +23,20 @@ fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled" success_msg: "{{ 'Configuring HA' if keycloak_quarkus_ha_enabled else 'Configuring standalone' }}" +- name: Validate OS family + ansible.builtin.assert: + that: + - ansible_os_family in ["RedHat", "Debian"] + quiet: true + fail_msg: "Can only install on RedHat or Debian OS families; found {{ ansible_os_family }}" + success_msg: "Installing on {{ ansible_os_family }}" + +- name: Load OS specific variables + ansible.builtin.include_vars: "vars/{{ ansible_os_family | lower }}.yml" + tags: + - always + - name: Ensure required packages are installed ansible.builtin.include_tasks: fastpackages.yml vars: - packages_list: - - "{{ keycloak_quarkus_jvm_package }}" - - unzip - - "{{ 'procps-ng' if ansible_facts.os_family == 'RedHat' else 'procps' }}" - - "{{ 'initscripts' if ansible_facts.os_family == 'RedHat' else 'apt' }}" - - "{{ 'tzdata-java' if ansible_facts.os_family == 'RedHat' else 'tzdata' }}" + packages_list: "{{ keycloak_prereq_package_list }}" diff --git a/roles/keycloak_quarkus/vars/debian.yml b/roles/keycloak_quarkus/vars/debian.yml new file mode 100644 index 0000000..6c7ed90 --- /dev/null +++ b/roles/keycloak_quarkus/vars/debian.yml @@ -0,0 +1,11 @@ +--- +keycloak_quarkus_jvm_package: openjdk-17-jdk-headless +keycloak_prereq_package_list: + - "{{ keycloak_quarkus_jvm_package }}" + - unzip + - procps + - apt + - tzdata +keycloak_quarkus_configure_iptables: True +keycloak_quarkus_sysconf_file: /etc/default/keycloak +keycloak_quarkus_pkg_java_home: "/lib/jvm/java-{{ keycloak_quarkus_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" diff --git a/roles/keycloak_quarkus/vars/redhat.yml b/roles/keycloak_quarkus/vars/redhat.yml new file mode 100644 index 0000000..775f983 --- /dev/null +++ b/roles/keycloak_quarkus/vars/redhat.yml @@ -0,0 +1,11 @@ +--- +keycloak_quarkus_jvm_package: java-17-openjdk-headless +keycloak_prereq_package_list: + - "{{ keycloak_quarkus_jvm_package }}" + - unzip + - procps-ng + - initscripts + - tzdata-java +keycloak_quarkus_configure_iptables: False +keycloak_quarkus_sysconf_file: /etc/sysconfig/keycloak +keycloak_quarkus_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" From 3b1534d700c02ca2d863a62cfa0b89e439fd440f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 10:19:28 +0100 Subject: [PATCH 180/376] refactor --- roles/keycloak_quarkus/tasks/debian.yml | 2 +- roles/keycloak_quarkus/tasks/fastpackages.yml | 2 +- roles/keycloak_quarkus/tasks/main.yml | 10 ++---- roles/keycloak_quarkus/tasks/systemd.yml | 33 ++----------------- .../templates/keycloak-sysconfig.j2 | 4 +-- .../templates/keycloak.service.j2 | 2 +- 6 files changed, 9 insertions(+), 44 deletions(-) diff --git a/roles/keycloak_quarkus/tasks/debian.yml b/roles/keycloak_quarkus/tasks/debian.yml index ffb1348..4a36661 100644 --- a/roles/keycloak_quarkus/tasks/debian.yml +++ b/roles/keycloak_quarkus/tasks/debian.yml @@ -1,6 +1,6 @@ --- - name: Include firewall config tasks ansible.builtin.include_tasks: iptables.yml - when: keycloak_configure_iptables + when: keycloak_quarkus_configure_iptables tags: - firewall diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml index 3b557ef..5affe64 100644 --- a/roles/keycloak_quarkus/tasks/fastpackages.yml +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -13,7 +13,7 @@ - name: "Install packages: {{ packages_to_install }}" become: true - ansible.builtin.yum: + ansible.builtin.dnf: name: "{{ packages_to_install }}" state: present when: diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 72f4fdd..86b3211 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -4,16 +4,10 @@ ansible.builtin.include_tasks: prereqs.yml tags: - prereqs + - always - name: Debian specific tasks - ansible.builtin.include_tasks: debian.yml - when: ansible_facts.os_family == "Debian" - tags: - - unbound - -- name: RedHat specific tasks - ansible.builtin.include_tasks: redhat.yml - when: ansible_facts.os_family == "RedHat" + ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml" tags: - unbound diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index 65aeeb3..58dbc7e 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -1,43 +1,14 @@ --- -- name: Determine JAVA_HOME for selected JVM RPM - ansible.builtin.set_fact: - rpm_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" - when: - - ansible_facts.os_family == "RedHat" - -- name: Determine JAVA_HOME for selected JVM RPM - ansible.builtin.set_fact: - rpm_java_home: "/lib/jvm/java-{{ keycloak_quarkus_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" - when: - - ansible_facts.os_family == "Debian" - - name: "Configure sysconfig file for {{ keycloak.service_name }} service" become: true ansible.builtin.template: src: keycloak-sysconfig.j2 - dest: /etc/default/keycloak + dest: "{{ keycloak_quarkus_sysconf_file }}" owner: root group: root mode: 0644 vars: - keycloak_rpm_java_home: "{{ rpm_java_home }}" - when: - - ansible_facts.os_family == "Debian" - notify: - - restart keycloak - -- name: "Configure sysconfig file for {{ keycloak.service_name }} service" - become: true - ansible.builtin.template: - src: keycloak-sysconfig.j2 - dest: /etc/sysconfig/keycloak - owner: root - group: root - mode: 0644 - vars: - keycloak_rpm_java_home: "{{ rpm_java_home }}" - when: - - ansible_facts.os_family == "RedHat" + keycloak_pkg_java_home: "{{ keycloak_quarkus_pkg_java_home }}" notify: - restart keycloak diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index aa6aef7..358794c 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -1,6 +1,6 @@ {{ ansible_managed | comment }} KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' -PATH={{ keycloak_quarkus_java_home | default(keycloak_rpm_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_rpm_java_home, true) }} +PATH={{ keycloak_quarkus_java_home | default(keycloak_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_pkg_java_home, true) }} JAVA_OPTS_APPEND={{ keycloak_quarkus_java_opts }} diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index af61007..3cdfacf 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -5,7 +5,7 @@ After=network.target [Service] Type=simple -EnvironmentFile=-/etc/sysconfig/keycloak +EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }} PIDFile={{ keycloak_quarkus_service_pidfile }} {% if keycloak_quarkus_start_dev %} ExecStart={{ keycloak.home }}/bin/kc.sh start-dev From 3400b64b105e19c2b8690bedba518fe8295130df Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 14:34:25 +0100 Subject: [PATCH 181/376] add to ci --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index afb1403..509bebb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode" ] + [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode", "debian" ] From 0e4df659f431f563b7800bf31b49867051305911 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 14:34:36 +0100 Subject: [PATCH 182/376] add test --- molecule/debian/converge.yml | 40 ++++++++++++++++++ molecule/debian/molecule.yml | 44 ++++++++++++++++++++ molecule/debian/prepare.yml | 11 +++++ molecule/debian/roles | 1 + molecule/debian/verify.yml | 52 ++++++++++++++++++++++++ roles/keycloak_quarkus/tasks/main.yml | 2 +- roles/keycloak_quarkus/tasks/prereqs.yml | 2 +- roles/keycloak_quarkus/vars/debian.yml | 2 +- roles/keycloak_quarkus/vars/redhat.yml | 2 +- 9 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 molecule/debian/converge.yml create mode 100644 molecule/debian/molecule.yml create mode 100644 molecule/debian/prepare.yml create mode 120000 molecule/debian/roles create mode 100644 molecule/debian/verify.yml diff --git a/molecule/debian/converge.yml b/molecule/debian/converge.yml new file mode 100644 index 0000000..0be6a85 --- /dev/null +++ b/molecule/debian/converge.yml @@ -0,0 +1,40 @@ +--- +- name: Converge + hosts: all + vars: + keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_admin_pass: "remembertochangeme" + keycloak_realm: TestRealm + keycloak_quarkus_log: file + keycloak_quarkus_frontend_url: 'http://localhost:8080/' + keycloak_quarkus_start_dev: True + keycloak_quarkus_proxy_mode: none + keycloak_client_default_roles: + - TestRoleAdmin + - TestRoleUser + keycloak_client_users: + - username: TestUser + password: password + client_roles: + - client: TestClient + role: TestRoleUser + - username: TestAdmin + password: password + client_roles: + - client: TestClient + role: TestRoleUser + - client: TestClient + role: TestRoleAdmin + keycloak_clients: + - name: TestClient + roles: "{{ keycloak_client_default_roles }}" + public_client: "{{ keycloak_client_public }}" + web_origins: "{{ keycloak_client_web_origins }}" + users: "{{ keycloak_client_users }}" + client_id: TestClient + attributes: + post.logout.redirect.uris: '/public/logout' + roles: + - role: keycloak_quarkus + - role: keycloak_realm + keycloak_realm: TestRealm diff --git a/molecule/debian/molecule.yml b/molecule/debian/molecule.yml new file mode 100644 index 0000000..78b102c --- /dev/null +++ b/molecule/debian/molecule.yml @@ -0,0 +1,44 @@ +--- +driver: + name: docker +platforms: + - name: instance + image: ghcr.io/hspaans/molecule-containers:debian-11 + pre_build_image: true + privileged: true + port_bindings: + - "8080/tcp" + - "8443/tcp" + - "8009/tcp" +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + ssh_connection: + pipelining: false + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: /usr/bin/python3 + env: + ANSIBLE_FORCE_COLOR: "true" + ANSIBLE_REMOTE_TMP: /tmp/.ansible/tmp +verifier: + name: ansible +scenario: + test_sequence: + - cleanup + - destroy + - create + - prepare + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/debian/prepare.yml b/molecule/debian/prepare.yml new file mode 100644 index 0000000..6025ef9 --- /dev/null +++ b/molecule/debian/prepare.yml @@ -0,0 +1,11 @@ +--- +- name: Prepare + hosts: all + gather_facts: yes + tasks: + - name: Install sudo + ansible.builtin.apt: + name: + - sudo + - openjdk-17-jdk-headless + state: present diff --git a/molecule/debian/roles b/molecule/debian/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/debian/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/molecule/debian/verify.yml b/molecule/debian/verify.yml new file mode 100644 index 0000000..040558a --- /dev/null +++ b/molecule/debian/verify.yml @@ -0,0 +1,52 @@ +--- +- name: Verify + hosts: all + vars: + keycloak_admin_password: "remembertochangeme" + keycloak_uri: "http://localhost:{{ 8080 + ( keycloak_jboss_port_offset | default(0) ) }}" + keycloak_management_port: "http://localhost:{{ 9990 + ( keycloak_jboss_port_offset | default(0) ) }}" + keycloak_jboss_port_offset: 10 + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + + - name: Check if keycloak service started + ansible.builtin.assert: + that: + - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" + + - name: Verify we are running on requested JAVA_HOME # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + ps -ef | grep '/opt/openjdk' | grep -v grep + args: + executable: /bin/bash + changed_when: False + + - name: Set internal envvar + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - name: Verify openid config + block: + - name: Fetch openID config # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + curl http://localhost:8080/realms/master/.well-known/openid-configuration -k | jq . + args: + executable: /bin/bash + delegate_to: localhost + register: openid_config + changed_when: False + - name: Verify endpoint URLs + ansible.builtin.assert: + that: + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'http://localhost:8080/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'http://localhost:8080/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'http://localhost:8080/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'http://localhost:8080/realms/master/protocol/openid-connect/token' + delegate_to: localhost + when: + - hera_home is defined + - hera_home | length == 0 diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 86b3211..decb63b 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -6,7 +6,7 @@ - prereqs - always -- name: Debian specific tasks +- name: Distro specific tasks ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml" tags: - unbound diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 7a33a48..a9fbeaa 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -39,4 +39,4 @@ - name: Ensure required packages are installed ansible.builtin.include_tasks: fastpackages.yml vars: - packages_list: "{{ keycloak_prereq_package_list }}" + packages_list: "{{ keycloak_quarkus_prereq_package_list }}" diff --git a/roles/keycloak_quarkus/vars/debian.yml b/roles/keycloak_quarkus/vars/debian.yml index 6c7ed90..8ff6775 100644 --- a/roles/keycloak_quarkus/vars/debian.yml +++ b/roles/keycloak_quarkus/vars/debian.yml @@ -1,6 +1,6 @@ --- keycloak_quarkus_jvm_package: openjdk-17-jdk-headless -keycloak_prereq_package_list: +keycloak_quarkus_prereq_package_list: - "{{ keycloak_quarkus_jvm_package }}" - unzip - procps diff --git a/roles/keycloak_quarkus/vars/redhat.yml b/roles/keycloak_quarkus/vars/redhat.yml index 775f983..e40a94a 100644 --- a/roles/keycloak_quarkus/vars/redhat.yml +++ b/roles/keycloak_quarkus/vars/redhat.yml @@ -1,6 +1,6 @@ --- keycloak_quarkus_jvm_package: java-17-openjdk-headless -keycloak_prereq_package_list: +keycloak_quarkus_prereq_package_list: - "{{ keycloak_quarkus_jvm_package }}" - unzip - procps-ng From e17505fe423eb2500aff3a73e0fa99941a462151 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 15:37:02 +0100 Subject: [PATCH 183/376] update molecule for debian container --- molecule/debian/molecule.yml | 4 ++++ molecule/requirements.yml | 2 +- roles/keycloak_quarkus/vars/debian.yml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/molecule/debian/molecule.yml b/molecule/debian/molecule.yml index 78b102c..afe29c5 100644 --- a/molecule/debian/molecule.yml +++ b/molecule/debian/molecule.yml @@ -10,6 +10,10 @@ platforms: - "8080/tcp" - "8443/tcp" - "8009/tcp" + cgroupns_mode: host + command: "/lib/systemd/systemd" + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw provisioner: name: ansible config_options: diff --git a/molecule/requirements.yml b/molecule/requirements.yml index c87fd9a..5c8bb43 100644 --- a/molecule/requirements.yml +++ b/molecule/requirements.yml @@ -5,7 +5,7 @@ collections: - name: community.general - name: ansible.posix - name: community.docker - version: ">=1.9.1" + version: ">=3.8.0" roles: - name: elan.simple_nginx_reverse_proxy diff --git a/roles/keycloak_quarkus/vars/debian.yml b/roles/keycloak_quarkus/vars/debian.yml index 8ff6775..e8c90e3 100644 --- a/roles/keycloak_quarkus/vars/debian.yml +++ b/roles/keycloak_quarkus/vars/debian.yml @@ -8,4 +8,4 @@ keycloak_quarkus_prereq_package_list: - tzdata keycloak_quarkus_configure_iptables: True keycloak_quarkus_sysconf_file: /etc/default/keycloak -keycloak_quarkus_pkg_java_home: "/lib/jvm/java-{{ keycloak_quarkus_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" +keycloak_quarkus_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_quarkus_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" From 467cfda0f7ef1d62157970d7e91a03b4929842e0 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 15:41:57 +0100 Subject: [PATCH 184/376] same changes for keycloak-legacy --- molecule/debian/converge.yml | 3 ++- molecule/debian/verify.yml | 12 ----------- roles/keycloak/defaults/main.yml | 2 -- roles/keycloak/tasks/main.yml | 11 ++-------- roles/keycloak/tasks/prereqs.yml | 20 ++++++++++++------ roles/keycloak/tasks/systemd.yml | 21 +------------------ .../keycloak/templates/keycloak-sysconfig.j2 | 2 +- roles/keycloak/templates/keycloak.service.j2 | 2 +- roles/keycloak/vars/debian.yml | 11 ++++++++++ roles/keycloak/vars/redhat.yml | 11 ++++++++++ 10 files changed, 43 insertions(+), 52 deletions(-) create mode 100644 roles/keycloak/vars/debian.yml create mode 100644 roles/keycloak/vars/redhat.yml diff --git a/molecule/debian/converge.yml b/molecule/debian/converge.yml index 0be6a85..17517b8 100644 --- a/molecule/debian/converge.yml +++ b/molecule/debian/converge.yml @@ -2,7 +2,6 @@ - name: Converge hosts: all vars: - keycloak_admin_password: "remembertochangeme" keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_realm: TestRealm keycloak_quarkus_log: file @@ -38,3 +37,5 @@ - role: keycloak_quarkus - role: keycloak_realm keycloak_realm: TestRealm + keycloak_admin_password: "remembertochangeme" + keycloak_context: '' diff --git a/molecule/debian/verify.yml b/molecule/debian/verify.yml index 040558a..59bf483 100644 --- a/molecule/debian/verify.yml +++ b/molecule/debian/verify.yml @@ -16,18 +16,6 @@ - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" - - name: Verify we are running on requested JAVA_HOME # noqa blocked_modules command-instead-of-module - ansible.builtin.shell: | - set -o pipefail - ps -ef | grep '/opt/openjdk' | grep -v grep - args: - executable: /bin/bash - changed_when: False - - - name: Set internal envvar - ansible.builtin.set_fact: - hera_home: "{{ lookup('env', 'HERA_HOME') }}" - - name: Verify openid config block: - name: Fetch openID config # noqa blocked_modules command-instead-of-module diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index 6658774..cfa9a3f 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -8,8 +8,6 @@ keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" keycloak_offline_install: false ### Install location and service settings -keycloak_jvm_package: "{{ 'java-1.8.0-openjdk-headless' if ansible_facts.os_family == 'RedHat' else 'openjdk-8-jdk-headless' }}" - keycloak_java_home: keycloak_dest: /opt/keycloak keycloak_jboss_home: "{{ keycloak_installdir }}" diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index 284900b..a21f359 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -5,15 +5,8 @@ tags: - prereqs -- name: Debian specific tasks - ansible.builtin.include_tasks: debian.yml - when: ansible_facts.os_family == "Debian" - tags: - - unbound - -- name: RedHat specific tasks - ansible.builtin.include_tasks: redhat.yml - when: ansible_facts.os_family == "RedHat" +- name: Distro specific tasks + ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml" tags: - unbound diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index 565931b..c92bb1c 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -36,12 +36,20 @@ success_msg: "Configuring JDBC persistence using {{ keycloak_jdbc_engine }} database" when: keycloak_db_enabled +- name: Validate OS family + ansible.builtin.assert: + that: + - ansible_os_family in ["RedHat", "Debian"] + quiet: true + fail_msg: "Can only install on RedHat or Debian OS families; found {{ ansible_os_family }}" + success_msg: "Installing on {{ ansible_os_family }}" + +- name: Load OS specific variables + ansible.builtin.include_vars: "vars/{{ ansible_os_family | lower }}.yml" + tags: + - always + - name: Ensure required packages are installed ansible.builtin.include_tasks: fastpackages.yml vars: - packages_list: - - "{{ keycloak_jvm_package }}" - - unzip - - "{{ 'procps-ng' if ansible_facts.os_family == 'RedHat' else 'procps' }}" - - "{{ 'initscripts' if ansible_facts.os_family == 'RedHat' else 'apt' }}" - - "{{ 'tzdata-java' if ansible_facts.os_family == 'RedHat' else 'tzdata' }}" + packages_list: "{{ keycloak_prereq_package_list }}" diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index cf84c32..40fa6b8 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -26,29 +26,10 @@ become: true ansible.builtin.template: src: keycloak-sysconfig.j2 - dest: /etc/default/keycloak + dest: "{{ keycloak_sysconf_file }}" owner: root group: root mode: 0644 - vars: - keycloak_rpm_java_home: "{{ rpm_java_home }}" - when: - - ansible_facts.os_family == "Debian" - notify: - - restart keycloak - -- name: "Configure sysconfig file for {{ keycloak.service_name }} service" - become: true - ansible.builtin.template: - src: keycloak-sysconfig.j2 - dest: /etc/sysconfig/keycloak - owner: root - group: root - mode: 0644 - vars: - keycloak_rpm_java_home: "{{ rpm_java_home }}" - when: - - ansible_facts.os_family == "RedHat" notify: - restart keycloak diff --git a/roles/keycloak/templates/keycloak-sysconfig.j2 b/roles/keycloak/templates/keycloak-sysconfig.j2 index 4c38522..33889df 100644 --- a/roles/keycloak/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak/templates/keycloak-sysconfig.j2 @@ -1,6 +1,6 @@ {{ ansible_managed | comment }} JAVA_OPTS='{{ keycloak_java_opts }}' -JAVA_HOME={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }} +JAVA_HOME={{ keycloak_java_home | default(keycloak_pkg_java_home, true) }} JBOSS_HOME={{ keycloak.home }} KEYCLOAK_BIND_ADDRESS={{ keycloak_bind_address }} KEYCLOAK_HTTP_PORT={{ keycloak_http_port }} diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 index eea3ba1..9a04e88 100644 --- a/roles/keycloak/templates/keycloak.service.j2 +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -11,7 +11,7 @@ StartLimitBurst={{ keycloak_service_startlimitburst }} User={{ keycloak_service_user }} Group={{ keycloak_service_group }} {% endif -%} -EnvironmentFile=-/etc/sysconfig/keycloak +EnvironmentFile=-{{ keycloak_sysconf_file }} PIDFile={{ keycloak_service_pidfile }} ExecStart={{ keycloak.home }}/bin/standalone.sh $WILDFLY_OPTS WorkingDirectory={{ keycloak.home }} diff --git a/roles/keycloak/vars/debian.yml b/roles/keycloak/vars/debian.yml new file mode 100644 index 0000000..ac3df14 --- /dev/null +++ b/roles/keycloak/vars/debian.yml @@ -0,0 +1,11 @@ +--- +keycloak_jvm_package: openjdk-11-jdk-headless +keycloak_prereq_package_list: + - "{{ keycloak_jvm_package }}" + - unzip + - procps + - apt + - tzdata +keycloak_configure_iptables: True +keycloak_sysconf_file: /etc/default/keycloak +keycloak_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" diff --git a/roles/keycloak/vars/redhat.yml b/roles/keycloak/vars/redhat.yml new file mode 100644 index 0000000..206251e --- /dev/null +++ b/roles/keycloak/vars/redhat.yml @@ -0,0 +1,11 @@ +--- +keycloak_jvm_package: java-1.8.0-openjdk-headless +keycloak_prereq_package_list: + - "{{ keycloak_jvm_package }}" + - unzip + - procps-ng + - initscripts + - tzdata-java +keycloak_configure_iptables: False +keycloak_sysconf_file: /etc/sysconfig/keycloak +keycloak_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" From 2bbf7d9cc4a94f75942d8a35a56abcd04a33cd3b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 25 Mar 2024 16:30:13 +0100 Subject: [PATCH 185/376] revert JVM var that cannot be overridden --- molecule/default/converge.yml | 2 +- roles/keycloak/meta/argument_specs.yml | 55 +------------------ roles/keycloak/tasks/systemd.yml | 12 ---- roles/keycloak/vars/debian.yml | 6 +- roles/keycloak/vars/redhat.yml | 7 +-- roles/keycloak_quarkus/defaults/main.yml | 4 +- .../keycloak_quarkus/meta/argument_specs.yml | 41 ++------------ roles/keycloak_quarkus/vars/debian.yml | 7 +-- roles/keycloak_quarkus/vars/redhat.yml | 7 +-- 9 files changed, 22 insertions(+), 119 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index ace4743..5927ff9 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -1,7 +1,7 @@ --- - name: Converge hosts: all - vars: + vars: keycloak_admin_password: "remembertochangeme" keycloak_jvm_package: java-11-openjdk-headless keycloak_modcluster_enabled: True diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index ca1cb8b..7ba6509 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -2,47 +2,38 @@ argument_specs: main: options: keycloak_version: - # line 3 of keycloak/defaults/main.yml default: "18.0.2" description: "keycloak.org package version" type: "str" keycloak_archive: - # line 4 of keycloak/defaults/main.yml default: "keycloak-legacy-{{ keycloak_version }}.zip" description: "keycloak install archive filename" type: "str" keycloak_configure_iptables: - # line 33 of keycloak/defaults/main.yml default: false description: "Ensure iptables is running and configure keycloak ports" type: "bool" keycloak_configure_firewalld: - # line 33 of keycloak/defaults/main.yml default: false description: "Ensure firewalld is running and configure keycloak ports" type: "bool" keycloak_download_url: - # line 5 of keycloak/defaults/main.yml default: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}" description: "Download URL for keycloak" type: "str" keycloak_download_url_9x: - # line 6 of keycloak/defaults/main.yml default: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}" description: "Download URL for keycloak (deprecated)" type: "str" keycloak_installdir: - # line 7 of keycloak/defaults/main.yml default: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" description: "Installation path" type: "str" keycloak_offline_install: - # line 20 of keycloak/defaults/main.yml default: false description: "Perform an offline install" type: "bool" keycloak_jvm_package: - # line 23 of keycloak/defaults/main.yml default: "java-1.8.0-openjdk-headless" description: "RHEL java package runtime rpm" type: "str" @@ -50,12 +41,10 @@ argument_specs: description: "JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path" type: "str" keycloak_dest: - # line 24 of keycloak/defaults/main.yml default: "/opt/keycloak" description: "Root installation directory" type: "str" keycloak_jboss_home: - # line 25 of keycloak/defaults/main.yml default: "{{ keycloak_installdir }}" description: "Installation work directory" type: "str" @@ -64,52 +53,42 @@ argument_specs: description: "Port offset for the JBoss socket binding" type: "int" keycloak_config_dir: - # line 26 of keycloak/defaults/main.yml default: "{{ keycloak_jboss_home }}/standalone/configuration" description: "Path for configuration" type: "str" keycloak_config_standalone_xml: - # line 27 of keycloak/defaults/main.yml default: "keycloak.xml" description: "Service configuration filename" type: "str" keycloak_config_path_to_standalone_xml: - # line 28 of keycloak/defaults/main.yml default: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}" description: "Custom path for configuration" type: "str" keycloak_config_override_template: - # line 30 of keycloak/defaults/main.yml default: "" description: "Path to custom template for standalone.xml configuration" type: "str" - keycloak_service_runas: - # line 20 of keycloak/defaults/main.yml + keycloak_service_runas: default: false description: "Enable execution of service as `keycloak_service_user`" type: "bool" keycloak_service_user: - # line 29 of keycloak/defaults/main.yml default: "keycloak" description: "posix account username" type: "str" keycloak_service_group: - # line 30 of keycloak/defaults/main.yml default: "keycloak" description: "posix account group" type: "str" keycloak_service_pidfile: - # line 31 of keycloak/defaults/main.yml default: "/run/keycloak/keycloak.pid" description: "PID file path for service" type: "str" keycloak_features: - # line 17 of keycloak/defaults/main.yml default: "[]" description: "List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]`" type: "list" keycloak_bind_address: - # line 34 of keycloak/defaults/main.yml default: "0.0.0.0" description: "Address for binding service ports" type: "str" @@ -118,52 +97,42 @@ argument_specs: description: "Address for binding the management ports" type: "str" keycloak_host: - # line 35 of keycloak/defaults/main.yml default: "localhost" description: "Hostname for service" type: "str" keycloak_http_port: - # line 36 of keycloak/defaults/main.yml default: 8080 description: "Listening HTTP port" type: "int" keycloak_https_port: - # line 37 of keycloak/defaults/main.yml default: 8443 description: "Listening HTTPS port" type: "int" keycloak_ajp_port: - # line 38 of keycloak/defaults/main.yml default: 8009 description: "Listening AJP port" type: "int" keycloak_jgroups_port: - # line 39 of keycloak/defaults/main.yml default: 7600 description: "jgroups cluster tcp port" type: "int" keycloak_management_http_port: - # line 40 of keycloak/defaults/main.yml default: 9990 description: "Management port (http)" type: "int" keycloak_management_https_port: - # line 41 of keycloak/defaults/main.yml default: 9993 description: "Management port (https)" type: "int" keycloak_java_opts: - # line 42 of keycloak/defaults/main.yml default: "-Xms1024m -Xmx2048m" description: "Additional JVM options" type: "str" keycloak_prefer_ipv4: - # line 43 of keycloak/defaults/main.yml default: true description: "Prefer IPv4 stack and addresses for port binding" type: "bool" keycloak_ha_enabled: - # line 46 of keycloak/defaults/main.yml default: false description: "Enable auto configuration for database backend, clustering and remote caches on infinispan" type: "bool" @@ -172,27 +141,22 @@ argument_specs: description: "Discovery protocol for HA cluster members" type: "str" keycloak_db_enabled: - # line 48 of keycloak/defaults/main.yml default: "{{ True if keycloak_ha_enabled else False }}" description: "Enable auto configuration for database backend" type: "bool" keycloak_admin_user: - # line 51 of keycloak/defaults/main.yml default: "admin" description: "Administration console user account" type: "str" keycloak_auth_realm: - # line 52 of keycloak/defaults/main.yml default: "master" description: "Name for rest authentication realm" type: "str" keycloak_auth_client: - # line 53 of keycloak/defaults/main.yml default: "admin-cli" description: "Authentication client for configuration REST calls" type: "str" keycloak_force_install: - # line 55 of keycloak/defaults/main.yml default: false description: "Remove pre-existing versions of service" type: "bool" @@ -201,7 +165,6 @@ argument_specs: description: "Enable configuration for modcluster subsystem" type: "bool" keycloak_modcluster_url: - # line 58 of keycloak/defaults/main.yml default: "localhost" description: "URL for the modcluster reverse proxy" type: "str" @@ -214,7 +177,6 @@ argument_specs: description: "List of modproxy node URLs in the format { host, port } for the modcluster reverse proxy" type: "list" keycloak_frontend_url: - # line 59 of keycloak/defaults/main.yml default: "http://localhost" description: "Frontend URL for keycloak endpoints when a reverse proxy is used" type: "str" @@ -223,77 +185,62 @@ argument_specs: description: "Force backend requests to use the frontend URL" type: "bool" keycloak_infinispan_user: - # line 62 of keycloak/defaults/main.yml default: "supervisor" description: "Username for connecting to infinispan" type: "str" keycloak_infinispan_pass: - # line 63 of keycloak/defaults/main.yml default: "supervisor" description: "Password for connecting to infinispan" type: "str" keycloak_infinispan_url: - # line 64 of keycloak/defaults/main.yml default: "localhost" description: "URL for the infinispan remote-cache server" type: "str" keycloak_infinispan_sasl_mechanism: - # line 65 of keycloak/defaults/main.yml default: "SCRAM-SHA-512" description: "Authentication type to infinispan server" type: "str" keycloak_infinispan_use_ssl: - # line 66 of keycloak/defaults/main.yml default: false description: "Enable hotrod client TLS communication" type: "bool" keycloak_infinispan_trust_store_path: - # line 68 of keycloak/defaults/main.yml default: "/etc/pki/java/cacerts" description: "TODO document argument" type: "str" keycloak_infinispan_trust_store_password: - # line 69 of keycloak/defaults/main.yml default: "changeit" description: "Path to truststore containing infinispan server certificate" type: "str" keycloak_jdbc_engine: - # line 72 of keycloak/defaults/main.yml default: "postgres" description: "Backend database flavour when db is enabled: [ postgres, mariadb, sqlserver ]" type: "str" keycloak_db_user: - # line 74 of keycloak/defaults/main.yml default: "keycloak-user" description: "Username for connecting to database" type: "str" keycloak_db_pass: - # line 75 of keycloak/defaults/main.yml default: "keycloak-pass" description: "Password for connecting to database" type: "str" keycloak_jdbc_url: - # line 76 of keycloak/defaults/main.yml default: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].url }}" description: "URL for connecting to backend database" type: "str" keycloak_jdbc_driver_version: - # line 77 of keycloak/defaults/main.yml default: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].version }}" description: "Version for the JDBC driver to download" type: "str" keycloak_admin_password: - # line 4 of keycloak/vars/main.yml required: true description: "Password for the administration console user account" type: "str" keycloak_url: - # line 12 of keycloak/vars/main.yml default: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}" description: "URL for configuration rest calls" type: "str" keycloak_management_url: - # line 13 of keycloak/vars/main.yml default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}" description: "URL for management console rest calls" type: "str" diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index 40fa6b8..797eb7b 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -10,18 +10,6 @@ notify: - restart keycloak -- name: Determine JAVA_HOME for selected JVM RPM - ansible.builtin.set_fact: - rpm_java_home: "/lib/jvm/java-{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" - when: - - ansible_facts.os_family == 'Debian' - -- name: Determine JAVA_HOME for selected JVM RPM - ansible.builtin.set_fact: - rpm_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" - when: - - ansible_facts.os_family == 'RedHat' - - name: "Configure sysconfig file for {{ keycloak.service_name }} service" become: true ansible.builtin.template: diff --git a/roles/keycloak/vars/debian.yml b/roles/keycloak/vars/debian.yml index ac3df14..60cdfa8 100644 --- a/roles/keycloak/vars/debian.yml +++ b/roles/keycloak/vars/debian.yml @@ -1,11 +1,11 @@ --- -keycloak_jvm_package: openjdk-11-jdk-headless +keycloak_varjvm_package: "{{ keycloak_jvm_package | default('openjdk-11-jdk-headless') }}" keycloak_prereq_package_list: - - "{{ keycloak_jvm_package }}" + - "{{ keycloak_varjvm_package }}" - unzip - procps - apt - tzdata keycloak_configure_iptables: True keycloak_sysconf_file: /etc/default/keycloak -keycloak_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" +keycloak_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_varjvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" diff --git a/roles/keycloak/vars/redhat.yml b/roles/keycloak/vars/redhat.yml index 206251e..6c36847 100644 --- a/roles/keycloak/vars/redhat.yml +++ b/roles/keycloak/vars/redhat.yml @@ -1,11 +1,10 @@ --- -keycloak_jvm_package: java-1.8.0-openjdk-headless +keycloak_varjvm_package: "{{ keycloak_jvm_package | default('java-1.8.0-openjdk-headless') }}" keycloak_prereq_package_list: - - "{{ keycloak_jvm_package }}" + - "{{ keycloak_varjvm_package }}" - unzip - procps-ng - initscripts - tzdata-java -keycloak_configure_iptables: False keycloak_sysconf_file: /etc/sysconfig/keycloak -keycloak_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" +keycloak_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_varjvm_package | regex_search('(?<=java-)[0-9.]+') }}" diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index e630bd3..d931cab 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -17,11 +17,13 @@ keycloak_quarkus_start_dev: false keycloak_quarkus_service_user: keycloak keycloak_quarkus_service_group: keycloak keycloak_quarkus_service_pidfile: "/run/keycloak/keycloak.pid" -keycloak_quarkus_configure_firewalld: false keycloak_quarkus_service_restart_always: false keycloak_quarkus_service_restart_on_failure: false keycloak_quarkus_service_restartsec: "10s" +keycloak_quarkus_configure_firewalld: false +keycloak_quarkus_configure_iptables: false + ### administrator console password keycloak_quarkus_admin_user: admin keycloak_quarkus_admin_pass: diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index b1baea2..c7cd446 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -2,32 +2,26 @@ argument_specs: main: options: keycloak_quarkus_version: - # line 3 of defaults/main.yml - default: "17.0.1" + default: "23.0.7" description: "keycloak.org package version" type: "str" keycloak_quarkus_archive: - # line 4 of defaults/main.yml default: "keycloak-{{ keycloak_quarkus_version }}.zip" description: "keycloak install archive filename" type: "str" keycloak_quarkus_download_url: - # line 5 of defaults/main.yml default: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" description: "Download URL for keycloak" type: "str" keycloak_quarkus_installdir: - # line 6 of defaults/main.yml default: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" description: "Installation path" type: "str" keycloak_quarkus_offline_install: - # line 9 of defaults/main.yml default: false description: "Perform an offline install" type: "bool" keycloak_quarkus_jvm_package: - # line 12 of defaults/main.yml default: "java-11-openjdk-headless" description: "RHEL java package runtime" type: "str" @@ -35,37 +29,34 @@ argument_specs: description: "JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path" type: "str" keycloak_quarkus_dest: - # line 13 of defaults/main.yml default: "/opt/keycloak" description: "Installation root path" type: "str" keycloak_quarkus_home: - # line 14 of defaults/main.yml default: "{{ keycloak_quarkus_installdir }}" description: "Installation work directory" type: "str" keycloak_quarkus_config_dir: - # line 15 of defaults/main.yml default: "{{ keycloak_quarkus_home }}/conf" description: "Path for configuration" type: "str" keycloak_quarkus_service_user: - # line 16 of defaults/main.yml default: "keycloak" description: "Posix account username" type: "str" keycloak_quarkus_service_group: - # line 17 of defaults/main.yml default: "keycloak" description: "Posix account group" type: "str" keycloak_quarkus_service_pidfile: - # line 18 of defaults/main.yml default: "/run/keycloak/keycloak.pid" description: "Pid file path for service" type: "str" keycloak_quarkus_configure_firewalld: - # line 19 of defaults/main.yml + default: false + description: "Ensure firewalld is running and configure keycloak ports" + type: "bool" + keycloak_quarkus_configure_iptables: default: false description: "Ensure firewalld is running and configure keycloak ports" type: "bool" @@ -90,12 +81,10 @@ argument_specs: description: "Password of console admin account" type: "str" keycloak_quarkus_master_realm: - # line 24 of defaults/main.yml default: "master" description: "Name for rest authentication realm" type: "str" keycloak_quarkus_bind_address: - # line 27 of defaults/main.yml default: "0.0.0.0" description: "Address for binding service ports" type: "str" @@ -116,7 +105,6 @@ argument_specs: description: "Enable listener on HTTP port" type: "bool" keycloak_quarkus_http_port: - # line 29 of defaults/main.yml default: 8080 description: "HTTP port" type: "int" @@ -157,27 +145,22 @@ argument_specs: description: "Password for the trust store" type: "str" keycloak_quarkus_https_port: - # line 30 of defaults/main.yml default: 8443 description: "HTTPS port" type: "int" keycloak_quarkus_ajp_port: - # line 31 of defaults/main.yml default: 8009 description: "AJP port" type: "int" keycloak_quarkus_jgroups_port: - # line 32 of defaults/main.yml default: 7800 description: "jgroups cluster tcp port" type: "int" keycloak_quarkus_java_opts: - # line 33 of defaults/main.yml default: "-Xms1024m -Xmx2048m" description: "Additional JVM options" type: "str" keycloak_quarkus_ha_enabled: - # line 36 of defaults/main.yml default: false description: "Enable auto configuration for database backend, clustering and remote caches on infinispan" type: "bool" @@ -186,7 +169,6 @@ argument_specs: description: "Discovery protocol for HA cluster members" type: "str" keycloak_quarkus_db_enabled: - # line 38 of defaults/main.yml default: "{{ True if keycloak_quarkus_ha_enabled else False }}" description: "Enable auto configuration for database backend" type: "str" @@ -204,7 +186,6 @@ argument_specs: description: "Service URL for the admin console" type: "str" keycloak_quarkus_metrics_enabled: - # line 43 of defaults/main.yml default: false description: "Whether to enable metrics" type: "bool" @@ -213,62 +194,50 @@ argument_specs: description: "If the server should expose health check endpoints" type: "bool" keycloak_quarkus_ispn_user: - # line 46 of defaults/main.yml default: "supervisor" description: "Username for connecting to infinispan" type: "str" keycloak_quarkus_ispn_pass: - # line 47 of defaults/main.yml default: "supervisor" description: "Password for connecting to infinispan" type: "str" keycloak_quarkus_ispn_hosts: - # line 48 of defaults/main.yml default: "localhost:11222" description: "host name/port for connecting to infinispan, eg. host1:11222;host2:11222" type: "str" keycloak_quarkus_ispn_sasl_mechanism: - # line 49 of defaults/main.yml default: "SCRAM-SHA-512" description: "Infinispan auth mechanism" type: "str" keycloak_quarkus_ispn_use_ssl: - # line 50 of defaults/main.yml default: false description: "Whether infinispan uses TLS connection" type: "bool" keycloak_quarkus_ispn_trust_store_path: - # line 52 of defaults/main.yml default: "/etc/pki/java/cacerts" description: "Path to infinispan server trust certificate" type: "str" keycloak_quarkus_ispn_trust_store_password: - # line 53 of defaults/main.yml default: "changeit" description: "Password for infinispan certificate keystore" type: "str" keycloak_quarkus_jdbc_engine: - # line 56 of defaults/main.yml default: "postgres" description: "Database engine [mariadb,postres,mssql]" type: "str" keycloak_quarkus_db_user: - # line 58 of defaults/main.yml default: "keycloak-user" description: "User for database connection" type: "str" keycloak_quarkus_db_pass: - # line 59 of defaults/main.yml default: "keycloak-pass" description: "Password for database connection" type: "str" keycloak_quarkus_jdbc_url: - # line 60 of defaults/main.yml default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].url }}" description: "JDBC URL for connecting to database" type: "str" keycloak_quarkus_jdbc_driver_version: - # line 61 of defaults/main.yml default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].version }}" description: "Version for JDBC driver" type: "str" diff --git a/roles/keycloak_quarkus/vars/debian.yml b/roles/keycloak_quarkus/vars/debian.yml index e8c90e3..a42eb5f 100644 --- a/roles/keycloak_quarkus/vars/debian.yml +++ b/roles/keycloak_quarkus/vars/debian.yml @@ -1,11 +1,10 @@ --- -keycloak_quarkus_jvm_package: openjdk-17-jdk-headless +keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('openjdk-17-jdk-headless') }}" keycloak_quarkus_prereq_package_list: - - "{{ keycloak_quarkus_jvm_package }}" + - "{{ keycloak_quarkus_varjvm_package }}" - unzip - procps - apt - tzdata -keycloak_quarkus_configure_iptables: True keycloak_quarkus_sysconf_file: /etc/default/keycloak -keycloak_quarkus_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_quarkus_jvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" +keycloak_quarkus_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_quarkus_varjvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" diff --git a/roles/keycloak_quarkus/vars/redhat.yml b/roles/keycloak_quarkus/vars/redhat.yml index e40a94a..c311321 100644 --- a/roles/keycloak_quarkus/vars/redhat.yml +++ b/roles/keycloak_quarkus/vars/redhat.yml @@ -1,11 +1,10 @@ --- -keycloak_quarkus_jvm_package: java-17-openjdk-headless +keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('java-17-openjdk-headless') }}" keycloak_quarkus_prereq_package_list: - - "{{ keycloak_quarkus_jvm_package }}" + - "{{ keycloak_quarkus_varjvm_package }}" - unzip - procps-ng - initscripts - tzdata-java -keycloak_quarkus_configure_iptables: False keycloak_quarkus_sysconf_file: /etc/sysconfig/keycloak -keycloak_quarkus_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}" +keycloak_quarkus_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_varjvm_package | regex_search('(?<=java-)[0-9.]+') }}" From c2e456e1d55ad8943c5f053d1e05b3f3fc0ce14f Mon Sep 17 00:00:00 2001 From: avskor Date: Thu, 4 Apr 2024 11:22:18 +0300 Subject: [PATCH 186/376] Fix #125. Permission error when the become variable is set to true in the playbook --- roles/keycloak_quarkus/tasks/install.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index e865b72..0162266 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -50,6 +50,7 @@ path: "{{ lookup('env', 'PWD') }}" register: local_path delegate_to: localhost + become: false - name: Download keycloak archive ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user @@ -57,6 +58,7 @@ dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" mode: 0640 delegate_to: localhost + become: false run_once: true when: - archive_path is defined From 8f8de33350fa7b2abfdd030ef26c0d1678cff0f4 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 8 Apr 2024 16:47:49 +0200 Subject: [PATCH 187/376] JVM arguments go IN JAVA_OPTS --- molecule/default/converge.yml | 2 +- roles/keycloak_quarkus/README.md | 4 +++- roles/keycloak_quarkus/defaults/main.yml | 7 ++++++- roles/keycloak_quarkus/meta/argument_specs.yml | 12 ++++++++++-- .../keycloak_quarkus/templates/keycloak-sysconfig.j2 | 2 +- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index 5927ff9..07cd724 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -52,7 +52,7 @@ pre_tasks: - name: "Retrieve assets server from env" ansible.builtin.set_fact: - assets_server: "{{ lookup('env','MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" + assets_server: "{{ lookup('env', 'MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" - name: "Set offline when assets server from env is defined" ansible.builtin.set_fact: diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 7c01eae..db02574 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -38,7 +38,9 @@ Role Defaults |`keycloak_quarkus_service_pidfile`| Pid file path for service | `/run/keycloak.pid` | |`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | -|`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | +|`keycloak_quarkus_java_opts`| Heap memory JVM setting | `-Xms1024m -Xmx2048m` | +|`keycloak_quarkus_java_jvm_opts`| Other JVM settings | same as keycloak | +|`keycloak_quarkus_java_opts`| JVM arguments; if overriden, it takes precedence over `keycloak_quarkus_java_*` | `{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}` | |`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | | |`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | | |`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index d931cab..6848acf 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -39,7 +39,12 @@ keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 keycloak_quarkus_ajp_port: 8009 keycloak_quarkus_jgroups_port: 7800 -keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m" +keycloak_quarkus_java_heap_opts: "-Xms1024m -Xmx2048m" +keycloak_quarkus_java_jvm_opts: "-XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 + -Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError + -Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC -XX:GCTimeRatio=4 + -XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512" +keycloak_quarkus_java_opts: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}" ### TLS/HTTPS configuration keycloak_quarkus_https_key_file_enabled: false diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index c7cd446..f4b87d7 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -156,9 +156,17 @@ argument_specs: default: 7800 description: "jgroups cluster tcp port" type: "int" - keycloak_quarkus_java_opts: + keycloak_quarkus_java_heap_opts: default: "-Xms1024m -Xmx2048m" - description: "Additional JVM options" + description: "Heap memory JVM setting" + type: "str" + keycloak_quarkus_java_jvm_opts: + default: "-XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError -Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512" + description: "Other JVM settings" + type: "str" + keycloak_quarkus_java_opts: + default: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}" + description: "JVM arguments, by default heap_opts + jvm_opts, if overriden it takes precedence over them" type: "str" keycloak_quarkus_ha_enabled: default: false diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index 358794c..2ec71e0 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -3,4 +3,4 @@ KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' PATH={{ keycloak_quarkus_java_home | default(keycloak_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_pkg_java_home, true) }} -JAVA_OPTS_APPEND={{ keycloak_quarkus_java_opts }} +JAVA_OPTS={{ keycloak_quarkus_java_opts }} From 8e2f3eb77f0687c12761305205b16c5efdfeaaaf Mon Sep 17 00:00:00 2001 From: Christian Iuga Date: Mon, 15 Apr 2024 14:41:56 +0200 Subject: [PATCH 188/376] Permit parse reverse proxy headers - Via created a new optional variable : keycloak_quarkus_proxy_headers - Fix enhancement #183 - see https://www.keycloak.org/server/reverseproxy about the official documentation --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/templates/keycloak.service.j2 | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index db02574..d6fa46d 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -54,7 +54,7 @@ Role Defaults |`keycloak_quarkus_https_trust_store_enabled`| Enalbe confiugration of a trust store | `False` | |`keycloak_quarkus_trust_store_file`| The file pat to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` | |`keycloak_quarkus_trust_store_password`| Password for the trust store | `""` | - +|`keycloak_quarkus_proxy_headers`| Parse reverse proxy headers (`forwarded` or `xforwardedPassword`) | `""` | * Hostname configuration diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 3cdfacf..77395c6 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -8,10 +8,10 @@ Type=simple EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }} PIDFile={{ keycloak_quarkus_service_pidfile }} {% if keycloak_quarkus_start_dev %} -ExecStart={{ keycloak.home }}/bin/kc.sh start-dev -{% else %} -ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized -{% endif %} +ExecStart={{ keycloak.home }}/bin/kc.sh start-dev{% if keycloak_quarkus_proxy_headers is defined %} --proxy-headers {{ keycloak_quarkus_proxy_headers }}{% endif -%}{{ '\n' }} +{% else -%} +ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized{% if keycloak_quarkus_proxy_headers is defined %} --proxy-headers {{ keycloak_quarkus_proxy_headers }}{% endif -%}{{ '\n' }} +{%- endif %} User={{ keycloak.service_user }} Group={{ keycloak.service_group }} {% if keycloak_quarkus_service_restart_always %} From 4aa862101c2f3b566686b8c77ea9d95407acb80e Mon Sep 17 00:00:00 2001 From: Christian Iuga Date: Mon, 15 Apr 2024 15:48:02 +0200 Subject: [PATCH 189/376] Add new variable keycloak_quarkus_proxy_headers into meta/argument_specs.yml Fix comment https://github.com/ansible-middleware/keycloak/pull/187#discussion_r1565772058 --- roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index f4b87d7..36f5adc 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -285,6 +285,10 @@ argument_specs: default: 'edge' type: "str" description: "The proxy address forwarding mode if the server is behind a reverse proxy. Set to 'none' if not using a proxy" + keycloak_quarkus_proxy_headers: + default: "" + type: "str" + description: "Parse reverse proxy headers (`forwarded` or `xforwardedPassword`), overrides the deprecated keycloak_quarkus_proxy_mode argument" keycloak_quarkus_start_dev: default: false type: "bool" From 27717d7b4eef4696dba6db8d3499c02782270854 Mon Sep 17 00:00:00 2001 From: Christian Iuga Date: Mon, 15 Apr 2024 15:50:55 +0200 Subject: [PATCH 190/376] Avoid cmd-line arguments Fix https://github.com/ansible-middleware/keycloak/pull/187#discussion_r1565779164 --- roles/keycloak_quarkus/templates/keycloak.service.j2 | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 77395c6..46c7f34 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -7,11 +7,15 @@ After=network.target Type=simple EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }} PIDFile={{ keycloak_quarkus_service_pidfile }} -{% if keycloak_quarkus_start_dev %} -ExecStart={{ keycloak.home }}/bin/kc.sh start-dev{% if keycloak_quarkus_proxy_headers is defined %} --proxy-headers {{ keycloak_quarkus_proxy_headers }}{% endif -%}{{ '\n' }} +{% if keycloak_quarkus_start_dev and keycloak_quarkus_proxy_headers is defined %} +ExecStart={{ keycloak.home }}/bin/kc.sh start-dev --proxy-headers {{ keycloak_quarkus_proxy_headers }} +{% elif keycloak_quarkus_start_dev and keycloak_quarkus_proxy_headers is not defined %} +ExecStart={{ keycloak.home }}/bin/kc.sh start-dev +{% elif not keycloak_quarkus_start_dev and keycloak_quarkus_proxy_headers is defined %} +ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized --proxy-headers {{ keycloak_quarkus_proxy_headers }} {% else -%} -ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized{% if keycloak_quarkus_proxy_headers is defined %} --proxy-headers {{ keycloak_quarkus_proxy_headers }}{% endif -%}{{ '\n' }} -{%- endif %} +ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized +{% endif %} User={{ keycloak.service_user }} Group={{ keycloak.service_group }} {% if keycloak_quarkus_service_restart_always %} From 3fbae4882e0d2c058cd42ee2cfd6b0b41f7a29f8 Mon Sep 17 00:00:00 2001 From: Christian Iuga Date: Tue, 16 Apr 2024 13:39:33 +0200 Subject: [PATCH 191/376] move keycloak_quarkus_proxy_headers into keycloak.conf --- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 7 ++++++- roles/keycloak_quarkus/templates/keycloak.service.j2 | 6 +----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index b23a250..20d3f7f 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -54,9 +54,14 @@ cache-config-file=cache-ispn.xml {% endif %} {% if keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %} -# Proxy +# Deprecated Proxy configuration proxy={{ keycloak_quarkus_proxy_mode }} {% endif %} +{% if keycloak_quarkus_proxy_headers is defined and keycloak_quarkus_proxy_headers != "none" %} +# Proxy +proxy-headers={{ keycloak_quarkus_proxy_headers }} +{% endif %} + spi-sticky-session-encoder-infinispan-should-attach-route={{ keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route | d(true) | lower }} # Transaction diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 46c7f34..30f4273 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -7,12 +7,8 @@ After=network.target Type=simple EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }} PIDFile={{ keycloak_quarkus_service_pidfile }} -{% if keycloak_quarkus_start_dev and keycloak_quarkus_proxy_headers is defined %} -ExecStart={{ keycloak.home }}/bin/kc.sh start-dev --proxy-headers {{ keycloak_quarkus_proxy_headers }} -{% elif keycloak_quarkus_start_dev and keycloak_quarkus_proxy_headers is not defined %} +{% if keycloak_quarkus_start_dev %} ExecStart={{ keycloak.home }}/bin/kc.sh start-dev -{% elif not keycloak_quarkus_start_dev and keycloak_quarkus_proxy_headers is defined %} -ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized --proxy-headers {{ keycloak_quarkus_proxy_headers }} {% else -%} ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized {% endif %} From ea57f8b68942a0c4f07b371bdc9f893242a55667 Mon Sep 17 00:00:00 2001 From: Christian Iuga Date: Tue, 16 Apr 2024 13:41:09 +0200 Subject: [PATCH 192/376] remove unwanted extra code --- roles/keycloak_quarkus/templates/keycloak.service.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 30f4273..3cdfacf 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -9,7 +9,7 @@ EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }} PIDFile={{ keycloak_quarkus_service_pidfile }} {% if keycloak_quarkus_start_dev %} ExecStart={{ keycloak.home }}/bin/kc.sh start-dev -{% else -%} +{% else %} ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized {% endif %} User={{ keycloak.service_user }} From 1229a0b0231fe837a77ed2b03866da7c7a0c4c57 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 10:46:23 +0200 Subject: [PATCH 193/376] Unrelax configuration file permissions --- roles/keycloak_quarkus/tasks/install.yml | 6 +++--- roles/keycloak_quarkus/tasks/jdbc_driver.yml | 2 +- roles/keycloak_quarkus/tasks/main.yml | 8 ++++---- roles/keycloak_quarkus/tasks/systemd.yml | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 0162266..3cf4b55 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -31,7 +31,7 @@ state: directory owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0750 + mode: '0750' ## check remote archive - name: Set download archive path @@ -56,7 +56,7 @@ ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user url: "{{ keycloak_quarkus_download_url }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" - mode: 0640 + mode: '0640' delegate_to: localhost become: false run_once: true @@ -118,7 +118,7 @@ dest: "{{ archive }}" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0640 + mode: '0640' register: new_version_downloaded when: - not archive_path.stat.exists diff --git a/roles/keycloak_quarkus/tasks/jdbc_driver.yml b/roles/keycloak_quarkus/tasks/jdbc_driver.yml index 0d03030..c95ef2b 100644 --- a/roles/keycloak_quarkus/tasks/jdbc_driver.yml +++ b/roles/keycloak_quarkus/tasks/jdbc_driver.yml @@ -6,7 +6,7 @@ dest: "{{ keycloak.home }}/providers" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0640 + mode: '0640' become: true notify: - restart keycloak diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index decb63b..ad97709 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -27,7 +27,7 @@ dest: "{{ keycloak.home }}/conf/keycloak.conf" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0644 + mode: '0640' become: true notify: - rebuild keycloak config @@ -39,7 +39,7 @@ dest: "{{ keycloak.home }}/conf/quarkus.properties" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0644 + mode: '0640' become: true notify: - restart keycloak @@ -64,7 +64,7 @@ dest: "{{ keycloak.home }}/conf/cache-ispn.xml" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0644 + mode: '0640' become: true notify: - rebuild keycloak config @@ -76,7 +76,7 @@ path: "{{ keycloak.log.file | dirname }}" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0775 + mode: '0775' become: true - name: Flush pending handlers diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index 58dbc7e..fcc1a71 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -6,7 +6,7 @@ dest: "{{ keycloak_quarkus_sysconf_file }}" owner: root group: root - mode: 0644 + mode: '0640' vars: keycloak_pkg_java_home: "{{ keycloak_quarkus_pkg_java_home }}" notify: @@ -18,7 +18,7 @@ dest: /etc/systemd/system/keycloak.service owner: root group: root - mode: 0644 + mode: '0644' become: true register: systemdunit notify: From ad6021c29a104447dc4d5429dca5b75cee7900bd Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 17 Apr 2024 08:58:43 +0000 Subject: [PATCH 194/376] Update changelog for release 2.1.1 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 18 ++++++++++++++++++ changelogs/changelog.yaml | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 15c2fbf..ce72edf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,24 @@ middleware\_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.1.1 +====== + +Minor Changes +------------- + +- Add reverse ``proxy_headers`` config, supersedes ``proxy_mode`` `#187 `_ +- Debian/Ubuntu compatibility `#178 `_ +- Use ``keycloak_realm`` as default for sub-entities `#180 `_ + +Bugfixes +-------- + +- Fix permissions on controller-side downloaded artifacts `#184 `_ +- JVM args moved to ``JAVA_OPTS`` envvar (instead of JAVA_OPTS_APPEND) `#186 `_ +- Unrelax configuration file permissions `#191 `_ +- Utilize comment filter for ``ansible_managed`` annotations `#176 `_ + v2.1.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index dd44253..a8ed730 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -419,3 +419,38 @@ releases: - 167.yaml - 171.yaml release_date: '2024-02-28' + 2.1.1: + changes: + bugfixes: + - 'Fix permissions on controller-side downloaded artifacts `#184 `_ + + ' + - 'JVM args moved to ``JAVA_OPTS`` envvar (instead of JAVA_OPTS_APPEND) `#186 + `_ + + ' + - 'Unrelax configuration file permissions `#191 `_ + + ' + - 'Utilize comment filter for ``ansible_managed`` annotations `#176 `_ + + ' + minor_changes: + - 'Add reverse ``proxy_headers`` config, supersedes ``proxy_mode`` `#187 `_ + + ' + - 'Debian/Ubuntu compatibility `#178 `_ + + ' + - 'Use ``keycloak_realm`` as default for sub-entities `#180 `_ + + ' + fragments: + - 176.yaml + - 178.yaml + - 180.yaml + - 184.yaml + - 186.yaml + - 187.yaml + - 191.yaml + release_date: '2024-04-17' From 2cf3e2470dab694e03926d8224d2d39d8a9b7654 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 17 Apr 2024 08:58:56 +0000 Subject: [PATCH 195/376] Bump version to 2.1.2 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index dd55345..a1e9cdb 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.1.1" +version: "2.1.2" readme: README.md authors: - Romain Pelisse From 5464a01a627b6f36e6b18b7e8dae7af630c1fec8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 11:08:04 +0200 Subject: [PATCH 196/376] ci: update doc links, test triggers --- .github/workflows/release.yml | 4 +++- docs/_gh_include/header.inc | 17 +++++++++-------- docs/index.rst | 17 +++++++++-------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7ea4aab..9dbf255 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,14 +8,16 @@ jobs: uses: ansible-middleware/github-actions/.github/workflows/release.yml@main with: collection_fqcn: 'middleware_automation.keycloak' + downstream_name: 'rhbk' secrets: galaxy_token: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} + jira_webhook: ${{ secrets.JIRA_WEBHOOK_CREATE_VERSION }} dispatch: needs: release strategy: matrix: - repo: ['ansible-middleware/cross-dc-rhsso-demo', 'ansible-middleware/flange-demo', 'ansible-middleware/ansible-middleware-ee'] + repo: ['ansible-middleware/ansible-middleware-ee'] runs-on: ubuntu-latest steps: - name: Repository Dispatch diff --git a/docs/_gh_include/header.inc b/docs/_gh_include/header.inc index 7c5103b..d97c7f1 100644 --- a/docs/_gh_include/header.inc +++ b/docs/_gh_include/header.inc @@ -24,14 +24,15 @@ diff --git a/docs/index.rst b/docs/index.rst index 6d8670c..38dec5b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -29,11 +29,12 @@ Welcome to Keycloak Collection documentation :maxdepth: 2 :caption: Middleware collections - Infinispan / Red Hat Data Grid - Keycloak / Red Hat Single Sign-On - Wildfly / Red Hat JBoss EAP - Tomcat / Red Hat JWS - ActiveMQ / Red Hat AMQ Broker - Kafka / Red Hat AMQ Streams - Red Hat CSP Download - JCliff + Infinispan / Red Hat Data Grid + Keycloak / Red Hat Single Sign-On + Wildfly / Red Hat JBoss EAP + Tomcat / Red Hat JWS + ActiveMQ / Red Hat AMQ Broker + Kafka / Red Hat AMQ Streams + Ansible Middleware utilities + Red Hat CSP Download + JCliff From 7bedb08f6eebde9caa8aacfdc628f54ac34ad32d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 11:14:38 +0200 Subject: [PATCH 197/376] ci: update release wf params --- .github/workflows/release.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9dbf255..d0d14d8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,6 +2,10 @@ name: Release collection on: workflow_dispatch: + inputs: + release_summary: + description: 'Optional release summary for changelogs' + required: false jobs: release: @@ -9,6 +13,7 @@ jobs: with: collection_fqcn: 'middleware_automation.keycloak' downstream_name: 'rhbk' + release_summary: "${{ github.event.inputs.release_summary }}" secrets: galaxy_token: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} jira_webhook: ${{ secrets.JIRA_WEBHOOK_CREATE_VERSION }} From 0c0c4e19eaeeca0e4450b1dbf6c33d4ef9725d77 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 11:57:44 +0200 Subject: [PATCH 198/376] downstream: update rhbk to 2.0.10 --- galaxy.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index a1e9cdb..dd55345 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.1.2" +version: "2.1.1" readme: README.md authors: - Romain Pelisse diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 36f5adc..da32de0 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -312,7 +312,7 @@ argument_specs: downstream: options: rhbk_version: - default: "22.0.6" + default: "22.0.10" description: "Red Hat Build of Keycloak version" type: "str" rhbk_archive: From 1ff6f237a904326b5efb0fea38a03698938a1209 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 11:58:11 +0200 Subject: [PATCH 199/376] Bump 2.1.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index dd55345..a1e9cdb 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.1.1" +version: "2.1.2" readme: README.md authors: - Romain Pelisse From d17c36425763d3ff0899d25e20478dee334ba6ec Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 12:14:25 +0200 Subject: [PATCH 200/376] downstream: ci sudo workaround --- galaxy.yml | 2 +- molecule/quarkus/prepare.yml | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index a1e9cdb..dd55345 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.1.2" +version: "2.1.1" readme: README.md authors: - Romain Pelisse diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 89ac436..03e5b89 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -2,15 +2,10 @@ - name: Prepare hosts: all tasks: - - name: Install sudo - ansible.builtin.package: - name: sudo - state: present - - name: "Display hera_home if defined." ansible.builtin.set_fact: hera_home: "{{ lookup('env', 'HERA_HOME') }}" - + - name: "Ensure common prepare phase are set." ansible.builtin.include_tasks: ../prepare.yml From 1f910bd40066b080d8d4ea28f585026afe79b3ca Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 15:45:11 +0200 Subject: [PATCH 201/376] Comprehensive linter warning fixes --- galaxy.yml | 1 - molecule/prepare.yml | 5 ++-- molecule/quarkus-devmode/prepare.yml | 6 ++--- roles/keycloak_quarkus/defaults/main.yml | 6 +++-- roles/keycloak_quarkus/handlers/main.yml | 2 +- .../keycloak_quarkus/meta/argument_specs.yml | 25 ++++++++++++++----- roles/keycloak_quarkus/tasks/fastpackages.yml | 7 +++--- roles/keycloak_quarkus/tasks/install.yml | 2 +- roles/keycloak_quarkus/tasks/jdbc_driver.yml | 1 - roles/keycloak_quarkus/tasks/prereqs.yml | 12 +++++---- roles/keycloak_quarkus/tasks/systemd.yml | 2 +- .../templates/keycloak-sysconfig.j2 | 4 +-- roles/keycloak_quarkus/vars/debian.yml | 2 +- roles/keycloak_realm/defaults/main.yml | 16 ++++++------ roles/keycloak_realm/meta/argument_specs.yml | 2 +- .../tasks/manage_client_users.yml | 2 +- .../tasks/manage_user_client_roles.yml | 8 ++++-- 17 files changed, 62 insertions(+), 41 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index dd55345..2e996a0 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -35,7 +35,6 @@ issues: https://github.com/ansible-middleware/keycloak/issues build_ignore: - .gitignore - .github - - .ansible-lint - .yamllint - '*.tar.gz' - '*.zip' diff --git a/molecule/prepare.yml b/molecule/prepare.yml index f122f9d..27486a3 100644 --- a/molecule/prepare.yml +++ b/molecule/prepare.yml @@ -25,7 +25,7 @@ fail_msg: "sudo is not installed on target system" - name: "Install iproute" - become: yes + become: true ansible.builtin.yum: name: - iproute @@ -33,7 +33,7 @@ - name: "Retrieve assets server from env" ansible.builtin.set_fact: - assets_server: "{{ lookup('env','MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" + assets_server: "{{ lookup('env', 'MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" - name: "Download artefacts only if assets_server is set" when: @@ -51,6 +51,7 @@ url: "{{ asset }}" dest: "{{ lookup('env', 'PWD') }}" validate_certs: no + mode: '0644' delegate_to: localhost loop: "{{ assets }}" loop_control: diff --git a/molecule/quarkus-devmode/prepare.yml b/molecule/quarkus-devmode/prepare.yml index 3a9bcb9..9ce721e 100644 --- a/molecule/quarkus-devmode/prepare.yml +++ b/molecule/quarkus-devmode/prepare.yml @@ -30,11 +30,11 @@ src: "{{ item }}" dest: /opt/openjdk force: true - with_fileglob: - - /usr/lib/jvm/java-17-openjdk* + with_fileglob: + - /usr/lib/jvm/java-17-openjdk* when: - ansible_facts.os_family == "Debian" - + - name: Link default logs directory ansible.builtin.file: state: link diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 6848acf..5821aca 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -86,7 +86,8 @@ keycloak_quarkus_proxy_mode: edge # disable xa transactions keycloak_quarkus_transaction_xa_enabled: true -# If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy +# If the route should be attached to cookies to reflect the node that owns a particular session. +# If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: true keycloak_quarkus_metrics_enabled: false @@ -120,7 +121,8 @@ keycloak_quarkus_default_jdbc: mssql: url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;' version: 12.2.0 - driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar" # cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/22.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver + driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar" + # cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/22.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver ### logging configuration keycloak_quarkus_log: file keycloak_quarkus_log_level: info diff --git a/roles/keycloak_quarkus/handlers/main.yml b/roles/keycloak_quarkus/handlers/main.yml index 6cbe276..82e229b 100644 --- a/roles/keycloak_quarkus/handlers/main.yml +++ b/roles/keycloak_quarkus/handlers/main.yml @@ -5,4 +5,4 @@ listen: "rebuild keycloak config" - name: "Restart {{ keycloak.service_name }}" ansible.builtin.include_tasks: restart.yml - listen: "restart keycloak" \ No newline at end of file + listen: "restart keycloak" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index da32de0..657ebbf 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -161,7 +161,10 @@ argument_specs: description: "Heap memory JVM setting" type: "str" keycloak_quarkus_java_jvm_opts: - default: "-XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError -Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512" + default: > + -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.err.encoding=UTF-8 + -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError -Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC + -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512 description: "Other JVM settings" type: "str" keycloak_quarkus_java_opts: @@ -272,7 +275,9 @@ argument_specs: keycloak_quarkus_log_max_file_size: default: 10M type: "str" - description: "Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): [0-9]+[KkMmGgTtPpEeZzYy]?. If no suffix is given, assume bytes." + description: > + Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular + expression): [0-9]+[KkMmGgTtPpEeZzYy]?. If no suffix is given, assume bytes. keycloak_quarkus_log_max_backup_index: default: 10 type: "str" @@ -280,7 +285,9 @@ argument_specs: keycloak_quarkus_log_file_suffix: default: '.yyyy-MM-dd.zip' type: "str" - description: "Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with .zip or .gz, the rotation file will also be compressed." + description: > + Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix. Note: If the suffix ends + with .zip or .gz, the rotation file will also be compressed. keycloak_quarkus_proxy_mode: default: 'edge' type: "str" @@ -300,15 +307,21 @@ argument_specs: keycloak_quarkus_hostname_strict: default: true type: "bool" - description: "Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless proxy verifies the Host header." + description: > + Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless + proxy verifies the Host header. keycloak_quarkus_hostname_strict_backchannel: default: false type: "bool" - description: "By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled." + description: > + By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all + applications use the public URL this option should be enabled. keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: default: true type: "bool" - description: "If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy" + description: > + If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies + and we rely on the session affinity capabilities from reverse proxy downstream: options: rhbk_version: diff --git a/roles/keycloak_quarkus/tasks/fastpackages.yml b/roles/keycloak_quarkus/tasks/fastpackages.yml index 5affe64..9dc1621 100644 --- a/roles/keycloak_quarkus/tasks/fastpackages.yml +++ b/roles/keycloak_quarkus/tasks/fastpackages.yml @@ -8,7 +8,8 @@ - name: "Add missing packages to the yum install list" ansible.builtin.set_fact: - packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" + packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | \ + map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" when: ansible_facts.os_family == "RedHat" - name: "Install packages: {{ packages_to_install }}" @@ -17,8 +18,8 @@ name: "{{ packages_to_install }}" state: present when: - - packages_to_install | default([]) | length > 0 - - ansible_facts.os_family == "RedHat" + - packages_to_install | default([]) | length > 0 + - ansible_facts.os_family == "RedHat" - name: "Install packages: {{ packages_list }}" become: true diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 3cf4b55..cc2aa7f 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -132,7 +132,7 @@ register: path_to_workdir become: true -- name: "Extract Keycloak archive on target" +- name: "Extract Keycloak archive on target" # noqa no-handler need to run this here ansible.builtin.unarchive: remote_src: true src: "{{ archive }}" diff --git a/roles/keycloak_quarkus/tasks/jdbc_driver.yml b/roles/keycloak_quarkus/tasks/jdbc_driver.yml index c95ef2b..310509a 100644 --- a/roles/keycloak_quarkus/tasks/jdbc_driver.yml +++ b/roles/keycloak_quarkus/tasks/jdbc_driver.yml @@ -1,5 +1,4 @@ --- - - name: "Retrieve JDBC Driver from {{ keycloak_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url }}" ansible.builtin.get_url: url: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url }}" diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index a9fbeaa..d344e98 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -4,7 +4,7 @@ that: - keycloak_quarkus_admin_pass | length > 12 quiet: true - fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass variable to a 12+ char long string" + fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass to a 12+ char long string" success_msg: "{{ 'Console administrator password OK' }}" - name: Validate relative path @@ -12,15 +12,17 @@ that: - keycloak_quarkus_http_relative_path is regex('^/.*') quiet: true - fail_msg: "the relative path must begin with /" - success_msg: "{{ 'relative path OK' }}" + fail_msg: "The relative path for keycloak_quarkus_http_relative_path must begin with /" + success_msg: "{{ 'Relative path OK' }}" - name: Validate configuration ansible.builtin.assert: that: - - (keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and not keycloak_quarkus_db_enabled) + - (keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or + (not keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or + (not keycloak_quarkus_ha_enabled and not keycloak_quarkus_db_enabled) quiet: true - fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled" + fail_msg: "HA setup requires a backend database service. Check keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled" success_msg: "{{ 'Configuring HA' if keycloak_quarkus_ha_enabled else 'Configuring standalone' }}" - name: Validate OS family diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index fcc1a71..47f0570 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -8,7 +8,7 @@ group: root mode: '0640' vars: - keycloak_pkg_java_home: "{{ keycloak_quarkus_pkg_java_home }}" + keycloak_sys_pkg_java_home: "{{ keycloak_quarkus_pkg_java_home }}" notify: - restart keycloak diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index 2ec71e0..4667596 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -1,6 +1,6 @@ {{ ansible_managed | comment }} KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' -PATH={{ keycloak_quarkus_java_home | default(keycloak_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_pkg_java_home, true) }} +PATH={{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }} JAVA_OPTS={{ keycloak_quarkus_java_opts }} diff --git a/roles/keycloak_quarkus/vars/debian.yml b/roles/keycloak_quarkus/vars/debian.yml index a42eb5f..e63c0d1 100644 --- a/roles/keycloak_quarkus/vars/debian.yml +++ b/roles/keycloak_quarkus/vars/debian.yml @@ -1,7 +1,7 @@ --- keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('openjdk-17-jdk-headless') }}" keycloak_quarkus_prereq_package_list: - - "{{ keycloak_quarkus_varjvm_package }}" + - "{{ keycloak_quarkus_varjvm_package }}" - unzip - procps - apt diff --git a/roles/keycloak_realm/defaults/main.yml b/roles/keycloak_realm/defaults/main.yml index c396481..e488207 100644 --- a/roles/keycloak_realm/defaults/main.yml +++ b/roles/keycloak_realm/defaults/main.yml @@ -26,14 +26,14 @@ keycloak_admin_password: '' # and users is a list of account, see below for the format definition # an empty name will skip the creation of the client # -#keycloak_clients: -# - name: '' -# roles: "{{ keycloak_client_default_roles }}" -# realm: "{{ keycloak_realm }}" -# public_client: "{{ keycloak_client_public }}" -# web_origins: "{{ keycloak_client_web_origins }}" -# redirect_uris: "{{ keycloak_client_redirect_uris }}" -# users: "{{ keycloak_client_users }}" +# keycloak_clients: +# - name: '' +# roles: "{{ keycloak_client_default_roles }}" +# realm: "{{ keycloak_realm }}" +# public_client: "{{ keycloak_client_public }}" +# web_origins: "{{ keycloak_client_web_origins }}" +# redirect_uris: "{{ keycloak_client_redirect_uris }}" +# users: "{{ keycloak_client_users }}" keycloak_clients: [] # list of roles to create in the client diff --git a/roles/keycloak_realm/meta/argument_specs.yml b/roles/keycloak_realm/meta/argument_specs.yml index ca174dc..ed87ee6 100644 --- a/roles/keycloak_realm/meta/argument_specs.yml +++ b/roles/keycloak_realm/meta/argument_specs.yml @@ -10,7 +10,7 @@ argument_specs: # line 5 of keycloak_realm/defaults/main.yml default: "/auth" description: "Context path for rest calls" - type: "str" + type: "str" keycloak_http_port: # line 4 of keycloak_realm/defaults/main.yml default: 8080 diff --git a/roles/keycloak_realm/tasks/manage_client_users.yml b/roles/keycloak_realm/tasks/manage_client_users.yml index ed9fb03..5234cb1 100644 --- a/roles/keycloak_realm/tasks/manage_client_users.yml +++ b/roles/keycloak_realm/tasks/manage_client_users.yml @@ -10,4 +10,4 @@ loop: "{{ client.users | flatten }}" loop_control: loop_var: user - when: "'client_roles' in user" \ No newline at end of file + when: "'client_roles' in user" diff --git a/roles/keycloak_realm/tasks/manage_user_client_roles.yml b/roles/keycloak_realm/tasks/manage_user_client_roles.yml index 4311daa..3884f42 100644 --- a/roles/keycloak_realm/tasks/manage_user_client_roles.yml +++ b/roles/keycloak_realm/tasks/manage_user_client_roles.yml @@ -12,7 +12,9 @@ - name: Check if Mapping is available ansible.builtin.uri: - url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | default(keycloak_realm) }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}/available" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | \ + default(keycloak_realm) }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | \ + selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}/available" method: GET status_code: - 200 @@ -23,7 +25,9 @@ - name: "Create Role Mapping" ansible.builtin.uri: - url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | default(keycloak_realm) }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}" + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | \ + default(keycloak_realm) }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | \ + selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}" method: POST body: - id: "{{ item.id }}" From 5b459f3ddeeb3f01b3597448bf7900d2aa090f48 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 16:48:24 +0200 Subject: [PATCH 202/376] ci: more linter fixes --- plugins/modules/keycloak_client.py | 2 +- plugins/modules/keycloak_role.py | 16 +- plugins/modules/keycloak_user_federation.py | 180 ++++++++++---------- roles/keycloak_quarkus/tasks/main.yml | 2 +- roles/keycloak_quarkus/tasks/start.yml | 2 +- roles/keycloak_quarkus/vars/debian.yml | 3 +- roles/keycloak_quarkus/vars/main.yml | 5 +- 7 files changed, 106 insertions(+), 104 deletions(-) diff --git a/plugins/modules/keycloak_client.py b/plugins/modules/keycloak_client.py index e1f0e19..dc824ca 100644 --- a/plugins/modules/keycloak_client.py +++ b/plugins/modules/keycloak_client.py @@ -637,7 +637,7 @@ EXAMPLES = ''' - test01 - test02 authentication_flow_binding_overrides: - browser: 4c90336b-bf1d-4b87-916d-3677ba4e5fbb + browser: 4c90336b-bf1d-4b87-916d-3677ba4e5fbb protocol_mappers: - config: access.token.claim: true diff --git a/plugins/modules/keycloak_role.py b/plugins/modules/keycloak_role.py index 0045d0e..558f362 100644 --- a/plugins/modules/keycloak_role.py +++ b/plugins/modules/keycloak_role.py @@ -142,14 +142,14 @@ EXAMPLES = ''' auth_password: PASSWORD name: my-new-role attributes: - attrib1: value1 - attrib2: value2 - attrib3: - - with - - numerous - - individual - - list - - items + attrib1: value1 + attrib2: value2 + attrib3: + - with + - numerous + - individual + - list + - items delegate_to: localhost ''' diff --git a/plugins/modules/keycloak_user_federation.py b/plugins/modules/keycloak_user_federation.py index bc84d8d..08c672e 100644 --- a/plugins/modules/keycloak_user_federation.py +++ b/plugins/modules/keycloak_user_federation.py @@ -475,99 +475,99 @@ author: ''' EXAMPLES = ''' - - name: Create LDAP user federation - middleware_automation.keycloak.keycloak_user_federation: - auth_keycloak_url: https://keycloak.example.com/auth - auth_realm: master - auth_username: admin - auth_password: password - realm: my-realm - name: my-ldap - state: present - provider_id: ldap - provider_type: org.keycloak.storage.UserStorageProvider - config: - priority: 0 - enabled: true - cachePolicy: DEFAULT - batchSizeForSync: 1000 - editMode: READ_ONLY - importEnabled: true - syncRegistrations: false - vendor: other - usernameLDAPAttribute: uid - rdnLDAPAttribute: uid - uuidLDAPAttribute: entryUUID - userObjectClasses: inetOrgPerson, organizationalPerson - connectionUrl: ldaps://ldap.example.com:636 - usersDn: ou=Users,dc=example,dc=com - authType: simple - bindDn: cn=directory reader - bindCredential: password - searchScope: 1 - validatePasswordPolicy: false - trustEmail: false - useTruststoreSpi: ldapsOnly - connectionPooling: true - pagination: true - allowKerberosAuthentication: false - debug: false - useKerberosForPasswordAuthentication: false - mappers: - - name: "full name" - providerId: "full-name-ldap-mapper" - providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" - config: - ldap.full.name.attribute: cn - read.only: true - write.only: false +- name: Create LDAP user federation + middleware_automation.keycloak.keycloak_user_federation: + auth_keycloak_url: https://keycloak.example.com/auth + auth_realm: master + auth_username: admin + auth_password: password + realm: my-realm + name: my-ldap + state: present + provider_id: ldap + provider_type: org.keycloak.storage.UserStorageProvider + config: + priority: 0 + enabled: true + cachePolicy: DEFAULT + batchSizeForSync: 1000 + editMode: READ_ONLY + importEnabled: true + syncRegistrations: false + vendor: other + usernameLDAPAttribute: uid + rdnLDAPAttribute: uid + uuidLDAPAttribute: entryUUID + userObjectClasses: inetOrgPerson, organizationalPerson + connectionUrl: ldaps://ldap.example.com:636 + usersDn: ou=Users,dc=example,dc=com + authType: simple + bindDn: cn=directory reader + bindCredential: password + searchScope: 1 + validatePasswordPolicy: false + trustEmail: false + useTruststoreSpi: ldapsOnly + connectionPooling: true + pagination: true + allowKerberosAuthentication: false + debug: false + useKerberosForPasswordAuthentication: false + mappers: + - name: "full name" + providerId: "full-name-ldap-mapper" + providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" + config: + ldap.full.name.attribute: cn + read.only: true + write.only: false - - name: Create Kerberos user federation - middleware_automation.keycloak.keycloak_user_federation: - auth_keycloak_url: https://keycloak.example.com/auth - auth_realm: master - auth_username: admin - auth_password: password - realm: my-realm - name: my-kerberos - state: present - provider_id: kerberos - provider_type: org.keycloak.storage.UserStorageProvider - config: - priority: 0 - enabled: true - cachePolicy: DEFAULT - kerberosRealm: EXAMPLE.COM - serverPrincipal: HTTP/host.example.com@EXAMPLE.COM - keyTab: keytab - allowPasswordAuthentication: false - updateProfileFirstLogin: false +- name: Create Kerberos user federation + middleware_automation.keycloak.keycloak_user_federation: + auth_keycloak_url: https://keycloak.example.com/auth + auth_realm: master + auth_username: admin + auth_password: password + realm: my-realm + name: my-kerberos + state: present + provider_id: kerberos + provider_type: org.keycloak.storage.UserStorageProvider + config: + priority: 0 + enabled: true + cachePolicy: DEFAULT + kerberosRealm: EXAMPLE.COM + serverPrincipal: HTTP/host.example.com@EXAMPLE.COM + keyTab: keytab + allowPasswordAuthentication: false + updateProfileFirstLogin: false - - name: Create sssd user federation - middleware_automation.keycloak.keycloak_user_federation: - auth_keycloak_url: https://keycloak.example.com/auth - auth_realm: master - auth_username: admin - auth_password: password - realm: my-realm - name: my-sssd - state: present - provider_id: sssd - provider_type: org.keycloak.storage.UserStorageProvider - config: - priority: 0 - enabled: true - cachePolicy: DEFAULT +- name: Create sssd user federation + middleware_automation.keycloak.keycloak_user_federation: + auth_keycloak_url: https://keycloak.example.com/auth + auth_realm: master + auth_username: admin + auth_password: password + realm: my-realm + name: my-sssd + state: present + provider_id: sssd + provider_type: org.keycloak.storage.UserStorageProvider + config: + priority: 0 + enabled: true + cachePolicy: DEFAULT - - name: Delete user federation - middleware_automation.keycloak.keycloak_user_federation: - auth_keycloak_url: https://keycloak.example.com/auth - auth_realm: master - auth_username: admin - auth_password: password - realm: my-realm - name: my-federation - state: absent +- name: Delete user federation + middleware_automation.keycloak.keycloak_user_federation: + auth_keycloak_url: https://keycloak.example.com/auth + auth_realm: master + auth_username: admin + auth_password: password + realm: my-realm + name: my-federation + state: absent ''' RETURN = ''' diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index ad97709..44fd3d1 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -73,7 +73,7 @@ - name: Ensure logdirectory exists ansible.builtin.file: state: directory - path: "{{ keycloak.log.file | dirname }}" + path: "{{ keycloak.log.file | dirname }}" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: '0775' diff --git a/roles/keycloak_quarkus/tasks/start.yml b/roles/keycloak_quarkus/tasks/start.yml index 7ccc1b9..a640e89 100644 --- a/roles/keycloak_quarkus/tasks/start.yml +++ b/roles/keycloak_quarkus/tasks/start.yml @@ -13,4 +13,4 @@ register: keycloak_status until: keycloak_status.status == 200 retries: 25 - delay: 10 \ No newline at end of file + delay: 10 diff --git a/roles/keycloak_quarkus/vars/debian.yml b/roles/keycloak_quarkus/vars/debian.yml index e63c0d1..29f190a 100644 --- a/roles/keycloak_quarkus/vars/debian.yml +++ b/roles/keycloak_quarkus/vars/debian.yml @@ -7,4 +7,5 @@ keycloak_quarkus_prereq_package_list: - apt - tzdata keycloak_quarkus_sysconf_file: /etc/default/keycloak -keycloak_quarkus_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_quarkus_varjvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" +keycloak_quarkus_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_quarkus_varjvm_package | \ + regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index 0ef6844..6f92f4f 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -1,10 +1,11 @@ --- -keycloak: +keycloak: # noqa var-naming this is an internal dict of interpolated values home: "{{ keycloak_quarkus_home }}" config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" + health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' \ + if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" From 50d189ee14f0825a80b554be3b833d4f0c32589a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 16:56:56 +0200 Subject: [PATCH 203/376] ci: more linter fixes --- plugins/modules/keycloak_user_federation.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/modules/keycloak_user_federation.py b/plugins/modules/keycloak_user_federation.py index 08c672e..36fe440 100644 --- a/plugins/modules/keycloak_user_federation.py +++ b/plugins/modules/keycloak_user_federation.py @@ -514,13 +514,13 @@ EXAMPLES = ''' debug: false useKerberosForPasswordAuthentication: false mappers: - - name: "full name" + - name: "full name" providerId: "full-name-ldap-mapper" providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" config: - ldap.full.name.attribute: cn - read.only: true - write.only: false + ldap.full.name.attribute: cn + read.only: true + write.only: false - name: Create Kerberos user federation middleware_automation.keycloak.keycloak_user_federation: From 921364b451c3bd7459cacc546605711f1eefa685 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 15 Apr 2024 15:28:00 +0200 Subject: [PATCH 204/376] Fix docs --- roles/keycloak_quarkus/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index d6fa46d..098af91 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -38,7 +38,7 @@ Role Defaults |`keycloak_quarkus_service_pidfile`| Pid file path for service | `/run/keycloak.pid` | |`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | -|`keycloak_quarkus_java_opts`| Heap memory JVM setting | `-Xms1024m -Xmx2048m` | +|`keycloak_quarkus_java_heap_opts`| Heap memory JVM setting | `-Xms1024m -Xmx2048m` | |`keycloak_quarkus_java_jvm_opts`| Other JVM settings | same as keycloak | |`keycloak_quarkus_java_opts`| JVM arguments; if overriden, it takes precedence over `keycloak_quarkus_java_*` | `{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}` | |`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | | From 60ca798e1a5f795fe6a9387d8cab97043b0809de Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 15 Apr 2024 15:43:59 +0200 Subject: [PATCH 205/376] Rename `keycloak_quarkus_*_store_*` attributes --- roles/keycloak_quarkus/README.md | 12 ++++--- roles/keycloak_quarkus/defaults/main.yml | 8 ++--- roles/keycloak_quarkus/handlers/main.yml | 5 +++ .../keycloak_quarkus/meta/argument_specs.yml | 16 ++++++--- roles/keycloak_quarkus/tasks/deprecations.yml | 36 +++++++++++++++++++ roles/keycloak_quarkus/tasks/main.yml | 5 +++ .../templates/keycloak.conf.j2 | 8 ++--- 7 files changed, 73 insertions(+), 17 deletions(-) create mode 100644 roles/keycloak_quarkus/tasks/deprecations.yml diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 098af91..a518cca 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -49,11 +49,13 @@ Role Defaults |`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `{{ keycloak.home }}/conf/server.key.pem` | |`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `{{ keycloak.home }}/conf/server.crt.pem` | |`keycloak_quarkus_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` | -|`keycloak_quarkus_key_store_file`| The file pat to the key store | `{{ keycloak.home }}/conf/key_store.p12` | -|`keycloak_quarkus_key_store_password`| Password for the key store | `""` | -|`keycloak_quarkus_https_trust_store_enabled`| Enalbe confiugration of a trust store | `False` | -|`keycloak_quarkus_trust_store_file`| The file pat to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` | -|`keycloak_quarkus_trust_store_password`| Password for the trust store | `""` | +|`keycloak_quarkus_key_store_file`| Deprecated, use `keycloak_quarkus_https_key_store_file` instead. || +|`keycloak_quarkus_key_store_password`| Deprecated, use `keycloak_quarkus_https_key_store_password` instead.|| +|`keycloak_quarkus_https_key_store_file`| The file path to the key store | `{{ keycloak.home }}/conf/key_store.p12` | +|`keycloak_quarkus_https_key_store_password`| Password for the key store | `""` | +|`keycloak_quarkus_https_trust_store_enabled`| Enable configuration of the https trust store | `False` | +|`keycloak_quarkus_https_trust_store_file`| The file path to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` | +|`keycloak_quarkus_https_trust_store_password`| Password for the trust store | `""` | |`keycloak_quarkus_proxy_headers`| Parse reverse proxy headers (`forwarded` or `xforwardedPassword`) | `""` | * Hostname configuration diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 5821aca..b1045e8 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -52,12 +52,12 @@ keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/server.key.pem" keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/server.crt.pem" #### key store configuration keycloak_quarkus_https_key_store_enabled: false -keycloak_quarkus_key_store_file: "{{ keycloak.home }}/conf/key_store.p12" -keycloak_quarkus_key_store_password: '' +keycloak_quarkus_https_key_store_file: "{{ keycloak.home }}/conf/key_store.p12" +keycloak_quarkus_https_key_store_password: '' ##### trust store configuration keycloak_quarkus_https_trust_store_enabled: false -keycloak_quarkus_trust_store_file: "{{ keycloak.home }}/conf/trust_store.p12" -keycloak_quarkus_trust_store_password: '' +keycloak_quarkus_https_trust_store_file: "{{ keycloak.home }}/conf/trust_store.p12" +keycloak_quarkus_https_trust_store_password: '' ### Enable configuration for database backend, clustering and remote caches on infinispan keycloak_quarkus_ha_enabled: false diff --git a/roles/keycloak_quarkus/handlers/main.yml b/roles/keycloak_quarkus/handlers/main.yml index 82e229b..bbdf61c 100644 --- a/roles/keycloak_quarkus/handlers/main.yml +++ b/roles/keycloak_quarkus/handlers/main.yml @@ -6,3 +6,8 @@ - name: "Restart {{ keycloak.service_name }}" ansible.builtin.include_tasks: restart.yml listen: "restart keycloak" +- name: "Print deprecation warning" + ansible.builtin.fail: + msg: "Deprecation warning: you are using the deprecated variable '{{ deprecated_variable | d('NotSet') }}', check docs on how to upgrade." + ignore_errors: True + listen: "print deprecation warning" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 657ebbf..928d900 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -125,22 +125,30 @@ argument_specs: description: "Enable configuration of HTTPS via a key store" type: "bool" keycloak_quarkus_key_store_file: + default: "" + description: "Deprecated, use `keycloak_quarkus_https_key_store_file` instead." + type: "str" + keycloak_quarkus_key_store_password: + default: "" + description: "Deprecated, use `keycloak_quarkus_https_key_store_password` instead." + type: "str" + keycloak_quarkus_https_key_store_file: default: "{{ keycloak.home }}/conf/key_store.p12" description: "The file path to the key store" type: "str" - keycloak_quarkus_key_store_password: + keycloak_quarkus_https_key_store_password: default: "" description: "Password for the key store" type: "str" keycloak_quarkus_https_trust_store_enabled: default: false - description: "Enalbe confiugration of a trust store" + description: "Enable configuration of the https trust store" type: "bool" - keycloak_quarkus_trust_store_file: + keycloak_quarkus_https_trust_store_file: default: "{{ keycloak.home }}/conf/trust_store.p12" description: "The file path to the trust store" type: "str" - keycloak_quarkus_trust_store_password: + keycloak_quarkus_https_trust_store_password: default: "" description: "Password for the trust store" type: "str" diff --git a/roles/keycloak_quarkus/tasks/deprecations.yml b/roles/keycloak_quarkus/tasks/deprecations.yml new file mode 100644 index 0000000..9fed05e --- /dev/null +++ b/roles/keycloak_quarkus/tasks/deprecations.yml @@ -0,0 +1,36 @@ +--- +- name: keycloak_quarkus_key_store -> keycloak_quarkus_http_key_store renaming + delegate_to: localhost + run_once: true + when: + - keycloak_quarkus_https_key_store_enabled + block: + - name: Ensure backward compatibility for `keycloak_quarkus_key_store_file`, superseded by `keycloak_quarkus_https_key_store_file` + when: + - keycloak_quarkus_key_store_file is defined + - keycloak_quarkus_key_store_file != '' + - keycloak_quarkus_https_key_store_file == keycloak.home + "/conf/key_store.p12" # default value + changed_when: true + ansible.builtin.set_fact: + keycloak_quarkus_https_key_store_file: "{{ keycloak_quarkus_key_store_file }}" + deprecated_variable: "keycloak_quarkus_key_store_file" # read in deprecation handler + notify: + - print deprecation warning + + - name: Flush handlers + meta: flush_handlers + + - name: Ensure backward compatibility for `keycloak_quarkus_key_store_password`, superseded by `keycloak_quarkus_https_key_store_password` + when: + - keycloak_quarkus_key_store_password is defined + - keycloak_quarkus_key_store_password != '' + - keycloak_quarkus_https_key_store_password == "" # default value + changed_when: true + ansible.builtin.set_fact: + keycloak_quarkus_https_key_store_password: "{{ keycloak_quarkus_key_store_password }}" + deprecated_variable: "keycloak_quarkus_key_store_password" # read in deprecation handler + notify: + - print deprecation warning + + - name: Flush handlers + meta: flush_handlers diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 44fd3d1..44c461f 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -6,6 +6,11 @@ - prereqs - always +- name: Check for deprecations + ansible.builtin.include_tasks: deprecations.yml + tags: + - always + - name: Distro specific tasks ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml" tags: diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 20d3f7f..d13a4cb 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -24,12 +24,12 @@ https-certificate-file={{ keycloak_quarkus_cert_file}} https-certificate-key-file={{ keycloak_quarkus_key_file }} {% endif %} {% if keycloak_quarkus_https_key_store_enabled %} -https-key-store-file={{ keycloak_quarkus_key_store_file }} -https-key-store-password={{ keycloak_quarkus_key_store_password }} +https-key-store-file={{ keycloak_quarkus_https_key_store_file }} +https-key-store-password={{ keycloak_quarkus_https_key_store_password }} {% endif %} {% if keycloak_quarkus_https_trust_store_enabled %} -https-trust-store-file={{ keycloak_quarkus_trust_store_file }} -https-trust-store-password={{ keycloak_quarkus_trust_store_password }} +https-trust-store-file={{ keycloak_quarkus_https_trust_store_file }} +https-trust-store-password={{ keycloak_quarkus_https_trust_store_password }} {% endif %} # Client URL configuration From 0ee29eb483a83704d6506d7628ecb72a9ba1ad2b Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 16 Apr 2024 09:39:03 +0200 Subject: [PATCH 206/376] #188: keycloak_quarkus: allow setting "sensitive options" using a Java KeyStore file #188 --- roles/keycloak_quarkus/README.md | 3 + roles/keycloak_quarkus/defaults/main.yml | 3 + .../keycloak_quarkus/meta/argument_specs.yml | 8 +++ roles/keycloak_quarkus/tasks/config_store.yml | 64 +++++++++++++++++++ roles/keycloak_quarkus/tasks/main.yml | 6 ++ .../templates/keycloak.conf.j2 | 9 +++ roles/keycloak_quarkus/vars/main.yml | 1 + 7 files changed, 94 insertions(+) create mode 100644 roles/keycloak_quarkus/tasks/config_store.yml diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index a518cca..ce45411 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -57,6 +57,9 @@ Role Defaults |`keycloak_quarkus_https_trust_store_file`| The file path to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` | |`keycloak_quarkus_https_trust_store_password`| Password for the trust store | `""` | |`keycloak_quarkus_proxy_headers`| Parse reverse proxy headers (`forwarded` or `xforwardedPassword`) | `""` | +|`keycloak_quarkus_config_key_store_file`| Path to the configuration key store; only used if `keycloak_quarkus_keystore_password` is not empty | `{{ keycloak.home }}/conf/conf_store.p12` if `keycloak_quarkus_keystore_password`!='', else '' | +|`keycloak_quarkus_config_key_store_password`| Password of the configuration key store; if non-empty, `keycloak_quarkus_db_pass` will be saved to the key store at `keycloak_quarkus_config_key_store_file` (instead of being written to the configuration file in clear text | `""` | + * Hostname configuration diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index b1045e8..37d7fb6 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -58,6 +58,9 @@ keycloak_quarkus_https_key_store_password: '' keycloak_quarkus_https_trust_store_enabled: false keycloak_quarkus_https_trust_store_file: "{{ keycloak.home }}/conf/trust_store.p12" keycloak_quarkus_https_trust_store_password: '' +### configuration key store configuration +keycloak_quarkus_config_key_store_file: "{{ keycloak.home }}/conf/conf_store.p12" +keycloak_quarkus_config_key_store_password: '' ### Enable configuration for database backend, clustering and remote caches on infinispan keycloak_quarkus_ha_enabled: false diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 928d900..0e7cdae 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -152,6 +152,14 @@ argument_specs: default: "" description: "Password for the trust store" type: "str" + keycloak_quarkus_config_key_store_file: + default: "{{ keycloak.home }}/conf/conf_store.p12" + description: "Path to the configuration key store; only used if `keycloak_quarkus_keystore_password` is not empty" + type: "str" + keycloak_quarkus_config_key_store_password: + default: "" + description: "Password of the configuration key store; if non-empty, `keycloak_quarkus_db_pass` will be saved to the key store at `keycloak_quarkus_config_key_store_file` (instead of being written to the configuration file in clear text" + type: "str" keycloak_quarkus_https_port: default: 8443 description: "HTTPS port" diff --git a/roles/keycloak_quarkus/tasks/config_store.yml b/roles/keycloak_quarkus/tasks/config_store.yml new file mode 100644 index 0000000..6919705 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/config_store.yml @@ -0,0 +1,64 @@ +--- +- name: "Check if keytool exists in path" + block: + - name: "Attempt to run keytool" + ansible.builtin.command: keytool -help + register: keytool_check + ignore_errors: true + + - name: "Fail when no keytool found" + when: keytool_check.rc != 0 + ansible.builtin.fail: + msg: "keytool NOT found in the PATH, but is required for setting up the configuration key store" + +- name: "Initialize configuration key store variables to be written" + ansible.builtin.set_fact: + store_items: + - key: "kc.db-password" + value: "{{ keycloak_quarkus_db_pass }}" + +- name: "Initialize empty configuration key store" + become: true + # keytool doesn't allow creating an empty key store, so this is a hacky way around it + ansible.builtin.shell: | + set -o nounset # abort on unbound variable + set -o pipefail # do not hide errors within pipes + set -o errexit # abort on nonzero exit status + + echo dummy | keytool -noprompt -importpass -alias dummy -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }} -storetype PKCS12 + keytool -delete -alias dummy -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }} + args: + creates: "{{ keycloak_quarkus_config_key_store_file }}" + +- name: "Set configuration key store using keytool" + ansible.builtin.shell: | + set -o nounset # abort on unbound variable + set -o pipefail # do not hide errors within pipes + + keytool -list -alias {{ item.key | quote }} -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }} + retVal=$? + + set -o errexit # abort on nonzero exit status + + if [ $retVal -eq 0 ]; then + # value is already in keystore, but keytool has no replace function: delete and re-create instead + # note that we can not read whether the value has changed either[^1], so we need to override it + # [^1]: https://stackoverflow.com/a/37491400 + keytool -delete -alias {{ item.key | quote }} -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }} + fi + + echo {{ item.value | quote }} | keytool -noprompt -importpass -alias {{ item.key | quote }} -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }} -storetype PKCS12 + with_items: "{{ store_items }}" + no_log: true + become: true + changed_when: true + notify: + - restart keycloak + +- name: "Set owner of configuration key store {{ keycloak_quarkus_config_key_store_file }}" + ansible.builtin.file: + path: "{{ keycloak_quarkus_config_key_store_file }}" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: '0400' + become: true diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 44c461f..8ca24cc 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -26,6 +26,12 @@ tags: - systemd +- name: Include configuration key store tasks + when: keycloak.config_key_store_enabled + ansible.builtin.include_tasks: config_store.yml + tags: + - install + - name: "Configure config for keycloak service" ansible.builtin.template: src: keycloak.conf.j2 diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index d13a4cb..6c9433e 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -5,8 +5,17 @@ db={{ keycloak_quarkus_jdbc_engine }} db-url={{ keycloak_quarkus_jdbc_url }} db-username={{ keycloak_quarkus_db_user }} +{% if not keycloak.config_key_store_enabled %} db-password={{ keycloak_quarkus_db_pass }} {% endif %} +{% endif %} + +{% if keycloak.config_key_store_enabled %} +# Config store +config-keystore={{ keycloak_quarkus_config_key_store_file }} +config-keystore-password={{ keycloak_quarkus_config_key_store_password }} +config-keystore-type=PKCS12 +{% endif %} # Observability metrics-enabled={{ keycloak_quarkus_metrics_enabled | lower }} diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index 6f92f4f..84fbeaa 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -10,6 +10,7 @@ keycloak: # noqa var-naming this is an internal dict of interpolated values service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" offline_install: "{{ keycloak_quarkus_offline_install }}" + config_key_store_enabled: "{{ keycloak_quarkus_config_key_store_password != '' }}" log: file: "{{ keycloak_quarkus_home }}/{{ keycloak_quarkus_log_file }}" level: "{{ keycloak_quarkus_log_level }}" From c38642e0cd4b6fd244350dc214bff6e2b713fc89 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 17 Apr 2024 14:33:37 +0200 Subject: [PATCH 207/376] #188: fail early when no `keytool` installed --- roles/keycloak_quarkus/tasks/config_store.yml | 12 ------------ roles/keycloak_quarkus/tasks/prereqs.yml | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/roles/keycloak_quarkus/tasks/config_store.yml b/roles/keycloak_quarkus/tasks/config_store.yml index 6919705..40acc65 100644 --- a/roles/keycloak_quarkus/tasks/config_store.yml +++ b/roles/keycloak_quarkus/tasks/config_store.yml @@ -1,16 +1,4 @@ --- -- name: "Check if keytool exists in path" - block: - - name: "Attempt to run keytool" - ansible.builtin.command: keytool -help - register: keytool_check - ignore_errors: true - - - name: "Fail when no keytool found" - when: keytool_check.rc != 0 - ansible.builtin.fail: - msg: "keytool NOT found in the PATH, but is required for setting up the configuration key store" - - name: "Initialize configuration key store variables to be written" ansible.builtin.set_fact: store_items: diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index d344e98..d96c09e 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -42,3 +42,17 @@ ansible.builtin.include_tasks: fastpackages.yml vars: packages_list: "{{ keycloak_quarkus_prereq_package_list }}" + +- name: "Validate keytool" + when: keycloak.config_key_store_enabled + block: + - name: "Attempt to run keytool" + changed_when: false + ansible.builtin.command: keytool -help + register: keytool_check + ignore_errors: true + + - name: "Fail when no keytool found" + when: keytool_check.rc != 0 + ansible.builtin.fail: + msg: "keytool NOT found in the PATH, but is required for setting up the configuration key store" From d469d389f3a886b2f9b0df09b1f20d94fd193242 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 17 Apr 2024 16:29:11 +0200 Subject: [PATCH 208/376] Fix linter issues --- roles/keycloak_quarkus/tasks/deprecations.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/tasks/deprecations.yml b/roles/keycloak_quarkus/tasks/deprecations.yml index 9fed05e..a81c808 100644 --- a/roles/keycloak_quarkus/tasks/deprecations.yml +++ b/roles/keycloak_quarkus/tasks/deprecations.yml @@ -1,5 +1,5 @@ --- -- name: keycloak_quarkus_key_store -> keycloak_quarkus_http_key_store renaming +- name: Check deprecation keycloak_quarkus_key_store -> keycloak_quarkus_http_key_store delegate_to: localhost run_once: true when: @@ -18,7 +18,7 @@ - print deprecation warning - name: Flush handlers - meta: flush_handlers + ansible.builtin.meta: flush_handlers - name: Ensure backward compatibility for `keycloak_quarkus_key_store_password`, superseded by `keycloak_quarkus_https_key_store_password` when: @@ -33,4 +33,4 @@ - print deprecation warning - name: Flush handlers - meta: flush_handlers + ansible.builtin.meta: flush_handlers From e991bd32c834190835ae892a61ac6fb5e897c366 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 17 Apr 2024 16:45:10 +0200 Subject: [PATCH 209/376] Fix typos --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index ce45411..e5bb5bf 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -56,7 +56,7 @@ Role Defaults |`keycloak_quarkus_https_trust_store_enabled`| Enable configuration of the https trust store | `False` | |`keycloak_quarkus_https_trust_store_file`| The file path to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` | |`keycloak_quarkus_https_trust_store_password`| Password for the trust store | `""` | -|`keycloak_quarkus_proxy_headers`| Parse reverse proxy headers (`forwarded` or `xforwardedPassword`) | `""` | +|`keycloak_quarkus_proxy_headers`| Parse reverse proxy headers (`forwarded` or `xforwarded`) | `""` | |`keycloak_quarkus_config_key_store_file`| Path to the configuration key store; only used if `keycloak_quarkus_keystore_password` is not empty | `{{ keycloak.home }}/conf/conf_store.p12` if `keycloak_quarkus_keystore_password`!='', else '' | |`keycloak_quarkus_config_key_store_password`| Password of the configuration key store; if non-empty, `keycloak_quarkus_db_pass` will be saved to the key store at `keycloak_quarkus_config_key_store_file` (instead of being written to the configuration file in clear text | `""` | diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 0e7cdae..6cca9de 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -311,7 +311,7 @@ argument_specs: keycloak_quarkus_proxy_headers: default: "" type: "str" - description: "Parse reverse proxy headers (`forwarded` or `xforwardedPassword`), overrides the deprecated keycloak_quarkus_proxy_mode argument" + description: "Parse reverse proxy headers (`forwarded` or `xforwarded`), overrides the deprecated keycloak_quarkus_proxy_mode argument" keycloak_quarkus_start_dev: default: false type: "bool" From 6706fd9bf512cfd5a20bada37f7bd80f70f88bd3 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 17:24:57 +0200 Subject: [PATCH 210/376] ci: bump and fix final linter warnings --- galaxy.yml | 2 +- roles/keycloak_realm/meta/argument_specs.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index 2e996a0..4eac8bd 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.1.1" +version: "2.1.2" readme: README.md authors: - Romain Pelisse diff --git a/roles/keycloak_realm/meta/argument_specs.yml b/roles/keycloak_realm/meta/argument_specs.yml index ed87ee6..b124be2 100644 --- a/roles/keycloak_realm/meta/argument_specs.yml +++ b/roles/keycloak_realm/meta/argument_specs.yml @@ -112,7 +112,7 @@ argument_specs: sso_enable: default: true description: "Enable Red Hat Single Sign-on installation" - type: "str" + type: "bool" rhbk_version: default: "22.0.6" description: "Red Hat Build of Keycloak version" @@ -132,4 +132,4 @@ argument_specs: rhbk_enable: default: true description: "Enable Red Hat Build of Keycloak installation" - type: "str" + type: "bool" From 74636e86299b9f37157198549344120817501c8f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 17:29:38 +0200 Subject: [PATCH 211/376] ci: final round of linting --- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- roles/keycloak_quarkus/tasks/install.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 657ebbf..57dec30 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -347,7 +347,7 @@ argument_specs: rhbk_enable: default: true description: "Enable Red Hat Build of Keycloak installation" - type: "str" + type: "bool" rhbk_offline_install: default: false description: "Perform an offline install" diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index cc2aa7f..818487f 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -22,7 +22,7 @@ name: "{{ keycloak.service_user }}" home: /opt/keycloak system: true - create_home: no + create_home: false - name: "Create {{ keycloak.service_name }} install location" become: true From 903938ca1684a3961705f2f58911aed8c74d8049 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 17 Apr 2024 15:49:00 +0000 Subject: [PATCH 212/376] Update changelog for release 2.1.2 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 3 +++ changelogs/changelog.yaml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ce72edf..e55bc0c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,9 @@ middleware\_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.1.2 +====== + v2.1.1 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index a8ed730..39ed404 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -454,3 +454,5 @@ releases: - 187.yaml - 191.yaml release_date: '2024-04-17' + 2.1.2: + release_date: '2024-04-17' From 462389cf0f84330ebee4b00756dd8151a926f723 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 17 Apr 2024 15:49:15 +0000 Subject: [PATCH 213/376] Bump version to 2.1.3 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 4eac8bd..0270d91 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.1.2" +version: "2.1.3" readme: README.md authors: - Romain Pelisse From 8060dd7fb84310ab1a348e69d7fb0f04895ccf78 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 17:51:33 +0200 Subject: [PATCH 214/376] Bump minor and start 2.2 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 0270d91..02838e3 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.1.3" +version: "2.2.0" readme: README.md authors: - Romain Pelisse From 5808d055ae21d293b4687be43596be84d8889b4a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 17:53:13 +0200 Subject: [PATCH 215/376] Update keycloak to 24.0 --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index e5bb5bf..4b7b46f 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `23.0.7` | +|`keycloak_quarkus_version`| keycloak.org package version | `24.0.3` | * Service configuration diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 37d7fb6..35ea39a 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 23.0.7 +keycloak_quarkus_version: 24.0.3 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index bdc0615..7a74e64 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -2,7 +2,7 @@ argument_specs: main: options: keycloak_quarkus_version: - default: "23.0.7" + default: "24.0.3" description: "keycloak.org package version" type: "str" keycloak_quarkus_archive: From 10057262bcbc8f92d8357dfc18ce705a8882df5e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 17 Apr 2024 18:07:42 +0200 Subject: [PATCH 216/376] 'fix' changelog --- CHANGELOG.rst | 12 ++++++++++++ changelogs/changelog.yaml | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e55bc0c..89d0992 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,6 +9,12 @@ This changelog describes changes after version 0.2.6. v2.1.2 ====== +Release Summary +--------------- + +Internal release, documentation or test changes only. + + v2.1.1 ====== @@ -275,6 +281,12 @@ Minor Changes v1.0.4 ====== +Release Summary +--------------- + +Internal release, documentation or test changes only. + + v1.0.3 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 39ed404..3fd8b1b 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -59,6 +59,10 @@ releases: - 31.yaml release_date: '2022-05-09' 1.0.4: + changes: + release_summary: 'Internal release, documentation or test changes only. + + ' release_date: '2022-05-11' 1.0.5: changes: @@ -455,4 +459,8 @@ releases: - 191.yaml release_date: '2024-04-17' 2.1.2: + changes: + release_summary: 'Internal release, documentation or test changes only. + + ' release_date: '2024-04-17' From 3e28b3f4f792a5f5027078e063446ec56ff3ff10 Mon Sep 17 00:00:00 2001 From: Deven Phillips Date: Wed, 17 Apr 2024 16:52:18 -0400 Subject: [PATCH 217/376] Added hostname-strict-https option --- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 6c9433e..f31e110 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -10,6 +10,10 @@ db-password={{ keycloak_quarkus_db_pass }} {% endif %} {% endif %} +{% if keycloak_quarkus_hostname_strict_https -%} +hostname-strict-https={{ keycloak_quarkus_hostname_strict_https }} +{% endif -%} + {% if keycloak.config_key_store_enabled %} # Config store config-keystore={{ keycloak_quarkus_config_key_store_file }} From 47e6644fdd165d6f1307003a70aadb22666c90b5 Mon Sep 17 00:00:00 2001 From: Deven Phillips Date: Wed, 17 Apr 2024 16:57:52 -0400 Subject: [PATCH 218/376] Ensure that value for keycloak_quarkus_hostname_strict_https is boolean, otherwise ignore it --- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index f31e110..3b064b1 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -10,8 +10,11 @@ db-password={{ keycloak_quarkus_db_pass }} {% endif %} {% endif %} -{% if keycloak_quarkus_hostname_strict_https -%} -hostname-strict-https={{ keycloak_quarkus_hostname_strict_https }} +{% if keycloak_quarkus_hostname_strict_https and keycloak_quarkus_hostname_strict_https is sameas true -%} +hostname-strict-https=true +{% endif -%} +{% if keycloak_quarkus_hostname_strict_https and keycloak_quarkus_hostname_strict_https is sameas false -%} +hostname-strict-https=false {% endif -%} {% if keycloak.config_key_store_enabled %} From cd8d61afc358fdf3e4fc917665f26beebb75381f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 18 Apr 2024 10:43:48 +0200 Subject: [PATCH 219/376] Update molecule test for keystore vault --- molecule/quarkus/converge.yml | 8 ++++++-- molecule/quarkus/prepare.yml | 8 +++++++- molecule/quarkus/verify.yml | 19 ++++++++++++++++--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 1b989ce..ea04de2 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -1,16 +1,20 @@ --- - name: Converge hosts: all - vars: + vars: keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_admin_password: "remembertochangeme" keycloak_realm: TestRealm keycloak_quarkus_host: instance keycloak_quarkus_log: file - keycloak_quarkus_https_key_file_enabled: True + keycloak_quarkus_log_level: debug + keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_key_file: "/opt/keycloak/certs/key.pem" keycloak_quarkus_cert_file: "/opt/keycloak/certs/cert.pem" keycloak_quarkus_log_target: /tmp/keycloak + keycloak_quarkus_ks_vault_enabled: true + keycloak_quarkus_ks_vault_file: "/opt/keycloak/certs/keystore.p12" + keycloak_quarkus_ks_vault_pass: keystorepassword roles: - role: keycloak_quarkus - role: keycloak_realm diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 03e5b89..b4f2431 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -21,7 +21,12 @@ path: "/opt/keycloak/certs/" mode: 0755 - - name: Copy certificates + - name: Create vault keystore + ansible.builtin.command: keytool -importpass -alias TestRealm_testalias -keystore keystore.p12 -storepass keystorepassword + delegate_to: localhost + changed_when: False + + - name: Copy certificates and vault become: yes ansible.builtin.copy: src: "{{ item }}" @@ -30,3 +35,4 @@ loop: - cert.pem - key.pem + - keystore.p12 diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index a58a13f..0216f1c 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -10,6 +10,7 @@ that: - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" + fail_msg: "Service not running" - name: Set internal envvar ansible.builtin.set_fact: @@ -40,7 +41,7 @@ - name: Check log folder ansible.builtin.stat: - path: "/tmp/keycloak" + path: /tmp/keycloak register: keycloak_log_folder - name: Check that keycloak log folder exists and is a link @@ -49,11 +50,12 @@ - keycloak_log_folder.stat.exists - not keycloak_log_folder.stat.isdir - keycloak_log_folder.stat.islnk + fail_msg: "Service log symlink not correctly created" - name: Check log file become: yes ansible.builtin.stat: - path: "/tmp/keycloak/keycloak.log" + path: /tmp/keycloak/keycloak.log register: keycloak_log_file - name: Check if keycloak file exists @@ -65,7 +67,7 @@ - name: Check default log folder become: yes ansible.builtin.stat: - path: "/var/log/keycloak" + path: /var/log/keycloak register: keycloak_default_log_folder failed_when: false @@ -73,3 +75,14 @@ ansible.builtin.assert: that: - not keycloak_default_log_folder.stat.exists + + - name: Read content of logs + ansible.builtin.slurp: + src: /tmp/keycloak/keycloak.log + register: slurped_log + + - name: Verify keystore vault loaded + ansible.builtin.assert: + that: + - "'Configured KeystoreVaultProviderFactory with the keystore file' in slurped_log.content | b64decode" + fail_msg: "Service failed to use keystore vault correctly" From 89db3fa36ffe43ead59ac8d5d498b4138ed7242f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 18 Apr 2024 10:44:17 +0200 Subject: [PATCH 220/376] Implement vault config --- roles/keycloak_quarkus/defaults/main.yml | 6 ++++++ roles/keycloak_quarkus/handlers/main.yml | 4 +++- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 8 ++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 35ea39a..e3e2504 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -135,3 +135,9 @@ keycloak_quarkus_log_target: /var/log/keycloak keycloak_quarkus_log_max_file_size: 10M keycloak_quarkus_log_max_backup_index: 10 keycloak_quarkus_log_file_suffix: '.yyyy-MM-dd.zip' + +# keystore-based vault +keycloak_quarkus_ks_vault_enabled: false +keycloak_quarkus_ks_vault_file: "{{ keycloak_quarkus_config_dir }}/keystore.p12" +keycloak_quarkus_ks_vault_type: PKCS12 +keycloak_quarkus_ks_vault_pass: diff --git a/roles/keycloak_quarkus/handlers/main.yml b/roles/keycloak_quarkus/handlers/main.yml index bbdf61c..965ea8f 100644 --- a/roles/keycloak_quarkus/handlers/main.yml +++ b/roles/keycloak_quarkus/handlers/main.yml @@ -3,11 +3,13 @@ - name: "Rebuild {{ keycloak.service_name }} config" ansible.builtin.include_tasks: rebuild_config.yml listen: "rebuild keycloak config" + - name: "Restart {{ keycloak.service_name }}" ansible.builtin.include_tasks: restart.yml listen: "restart keycloak" + - name: "Print deprecation warning" ansible.builtin.fail: msg: "Deprecation warning: you are using the deprecated variable '{{ deprecated_variable | d('NotSet') }}', check docs on how to upgrade." - ignore_errors: True + ignore_errors: true listen: "print deprecation warning" diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 6c9433e..17ba34b 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -82,3 +82,11 @@ log={{ keycloak_quarkus_log }} log-level={{ keycloak.log.level }} log-file={{ keycloak.log.file }} log-file-format={{ keycloak.log.format }} + +# Vault +{% if keycloak_quarkus_ks_vault_enabled %} +vault=keystore +vault-file={{ keycloak_quarkus_ks_vault_file }} +vault-type={{ keycloak_quarkus_ks_vault_type }} +vault-pass={{ keycloak_quarkus_ks_vault_pass }} +{% endif %} From d06dcea9988b8be7a92b9b528938cad9edefa8d3 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 18 Apr 2024 10:49:38 +0200 Subject: [PATCH 221/376] Add argument specs, update README --- roles/keycloak_quarkus/README.md | 25 +++++++++++++------ .../keycloak_quarkus/meta/argument_specs.yml | 16 ++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 4b7b46f..52304e6 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -7,14 +7,14 @@ Install [keycloak](https://keycloak.org/) >= 20.0.0 (quarkus) server configurati Role Defaults ------------- -* Installation options +#### Installation options | Variable | Description | Default | |:---------|:------------|:--------| |`keycloak_quarkus_version`| keycloak.org package version | `24.0.3` | -* Service configuration +#### Service configuration | Variable | Description | Default | |:---------|:------------|:--------| @@ -61,7 +61,7 @@ Role Defaults |`keycloak_quarkus_config_key_store_password`| Password of the configuration key store; if non-empty, `keycloak_quarkus_db_pass` will be saved to the key store at `keycloak_quarkus_config_key_store_file` (instead of being written to the configuration file in clear text | `""` | -* Hostname configuration +#### Hostname configuration | Variable | Description | Default | |:---------|:------------|:--------| @@ -70,7 +70,7 @@ Role Defaults |`keycloak_quarkus_hostname_strict_backchannel`| By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled. | `false` | -* Database configuration +#### Database configuration | Variable | Description | Default | |:---------|:------------|:--------| @@ -81,7 +81,7 @@ Role Defaults |`keycloak_quarkus_jdbc_driver_version` | Version for JDBC driver | `9.4.1212` | -* Remote caches configuration +#### Remote caches configuration | Variable | Description | Default | |:---------|:------------|:--------| @@ -94,7 +94,7 @@ Role Defaults |`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` | -* Install options +#### Install options | Variable | Description | Default | |:---------|:------------|:---------| @@ -105,7 +105,7 @@ Role Defaults |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | -* Miscellaneous configuration +#### Miscellaneous configuration | Variable | Description | Default | |:---------|:------------|:--------| @@ -132,6 +132,16 @@ Role Defaults |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | |`keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route`| If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy | `True` | + +#### Vault SPI + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_ks_vault_enabled`| Whether to enable the vault SPI | `false` | +|`keycloak_quarkus_ks_vault_file`| The keystore path for the vault SPI | `{{ keycloak_quarkus_config_dir }}/keystore.p12` | +|`keycloak_quarkus_ks_vault_type`| Type of the keystore used for the vault SPI | `PKCS12` | + + Role Variables -------------- @@ -140,6 +150,7 @@ Role Variables |`keycloak_quarkus_admin_pass`| Password of console admin account | `yes` | |`keycloak_quarkus_frontend_url`| Base URL for frontend URLs, including scheme, host, port and path | `no` | |`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` | +|`keycloak_quarkus_ks_vault_pass`| The password for accessing the keystore vault SPI | `no` | License diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 7a74e64..0f4ea98 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -338,6 +338,22 @@ argument_specs: description: > If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy + keycloak_quarkus_ks_vault_enabled: + default: false + type: "bool" + description: "Whether to enable vault SPI" + keycloak_quarkus_ks_vault_file: + default: "{{ keycloak_quarkus_config_dir }}/keystore.p12" + type: "str" + description: "The keystore path for the vault SPI" + keycloak_quarkus_ks_vault_type: + default: "PKCS12" + type: "str" + description: "Type of the keystore used for the vault SPI" + keycloak_quarkus_ks_vault_pass: + required: false + type: "str" + description: "The password for accessing the keystore vault SPI" downstream: options: rhbk_version: From ff198bcd3e95646ee98b9fd755af0c5aa1785ace Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 18 Apr 2024 11:06:14 +0200 Subject: [PATCH 222/376] workaround debug logfile too long for slurp --- molecule/quarkus/verify.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 0216f1c..1efe9dd 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -76,13 +76,10 @@ that: - not keycloak_default_log_folder.stat.exists - - name: Read content of logs - ansible.builtin.slurp: - src: /tmp/keycloak/keycloak.log + - name: Verify vault SPI in logfile + ansible.builtin.shell: | + set -o pipefail + zgrep 'Configured KeystoreVaultProviderFactory with the keystore file' /opt/keycloak/keycloak-*/data/log/keycloak.log*zip + changed_when: false + failed_when: slurped_log.rc != 0 register: slurped_log - - - name: Verify keystore vault loaded - ansible.builtin.assert: - that: - - "'Configured KeystoreVaultProviderFactory with the keystore file' in slurped_log.content | b64decode" - fail_msg: "Service failed to use keystore vault correctly" From b8cba487acc71c0cfa7858b61aac3c5c82a94699 Mon Sep 17 00:00:00 2001 From: Deven Phillips Date: Thu, 18 Apr 2024 13:15:46 -0400 Subject: [PATCH 223/376] Add better error trapping for booleans --- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 3b064b1..86d6628 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -10,10 +10,10 @@ db-password={{ keycloak_quarkus_db_pass }} {% endif %} {% endif %} -{% if keycloak_quarkus_hostname_strict_https and keycloak_quarkus_hostname_strict_https is sameas true -%} +{% if keycloak_quarkus_hostname_strict_https is defined and keycloak_quarkus_hostname_strict_https is sameas true -%} hostname-strict-https=true {% endif -%} -{% if keycloak_quarkus_hostname_strict_https and keycloak_quarkus_hostname_strict_https is sameas false -%} +{% if keycloak_quarkus_hostname_strict_https is defined and keycloak_quarkus_hostname_strict_https is sameas false -%} hostname-strict-https=false {% endif -%} From 289b4767e0ca428a0e1e3526cc652a4609fa6d57 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Fri, 19 Apr 2024 08:14:58 +0200 Subject: [PATCH 224/376] #190: remove `keycloak_quarkus_admin_user[_pass]` once keycloak is bootstrapped --- roles/keycloak_quarkus/README.md | 8 +++++++ roles/keycloak_quarkus/handlers/main.yml | 4 +++- roles/keycloak_quarkus/tasks/bootstrapped.yml | 16 +++++++++++++ roles/keycloak_quarkus/tasks/install.yml | 7 ++++++ roles/keycloak_quarkus/tasks/main.yml | 23 +++++++++++++++---- .../templates/keycloak-sysconfig.j2 | 4 ++++ .../templates/keycloak.fact.j2 | 2 ++ roles/keycloak_quarkus/vars/main.yml | 1 + 8 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 roles/keycloak_quarkus/tasks/bootstrapped.yml create mode 100644 roles/keycloak_quarkus/templates/keycloak.fact.j2 diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 52304e6..fb41533 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -152,6 +152,14 @@ Role Variables |`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` | |`keycloak_quarkus_ks_vault_pass`| The password for accessing the keystore vault SPI | `no` | +Role custom facts +----------------- + +The role uses the following [custom facts](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_vars_facts.html#adding-custom-facts) found in `/etc/ansible/facts.d/keycloak.fact` (and thus identified by the `ansible_local.keycloak.` prefix): + +| Variable | Description | +|:---------|:------------| +|`general.bootstrapped` | A custom fact indicating whether this role has been used for bootstrapping keycloak on the respective host before; set to `false` (e.g., when starting off with a new, empty database) ensures that the initial admin user as defined by `keycloak_quarkus_admin_user[_pass]` gets created | License ------- diff --git a/roles/keycloak_quarkus/handlers/main.yml b/roles/keycloak_quarkus/handlers/main.yml index 965ea8f..d6b2220 100644 --- a/roles/keycloak_quarkus/handlers/main.yml +++ b/roles/keycloak_quarkus/handlers/main.yml @@ -3,7 +3,9 @@ - name: "Rebuild {{ keycloak.service_name }} config" ansible.builtin.include_tasks: rebuild_config.yml listen: "rebuild keycloak config" - +- name: "Bootstrapped" + ansible.builtin.include_tasks: bootstrapped.yml + listen: bootstrapped - name: "Restart {{ keycloak.service_name }}" ansible.builtin.include_tasks: restart.yml listen: "restart keycloak" diff --git a/roles/keycloak_quarkus/tasks/bootstrapped.yml b/roles/keycloak_quarkus/tasks/bootstrapped.yml new file mode 100644 index 0000000..46278ab --- /dev/null +++ b/roles/keycloak_quarkus/tasks/bootstrapped.yml @@ -0,0 +1,16 @@ +--- +- name: Write ansible custom facts + become: true + ansible.builtin.template: + src: keycloak.fact.j2 + dest: /etc/ansible/facts.d/keycloak.fact + mode: '0644' + vars: + bootstrapped: true + +- name: Re-read custom facts + ansible.builtin.setup: + filter: ansible_local + +- name: Ensure that `KEYCLOAK_ADMIN[_PASSWORD]` get purged + ansible.builtin.include_tasks: systemd.yml diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 818487f..085f3d7 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -33,6 +33,13 @@ group: "{{ keycloak.service_group }}" mode: '0750' +- name: Create directory for ansible custom facts + become: true + ansible.builtin.file: + state: directory + recurse: true + path: /etc/ansible/facts.d + ## check remote archive - name: Set download archive path ansible.builtin.set_fact: diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 8ca24cc..4c0db72 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -96,11 +96,6 @@ - name: "Start and wait for keycloak service" ansible.builtin.include_tasks: start.yml -- name: Check service status - ansible.builtin.command: "systemctl status keycloak" - register: keycloak_service_status - changed_when: false - - name: Link default logs directory ansible.builtin.file: state: link @@ -108,3 +103,21 @@ dest: "{{ keycloak_quarkus_log_target }}" force: true become: true + +- name: Check service status + ansible.builtin.systemd_service: + name: "{{ keycloak.service_name }}" + register: keycloak_service_status + changed_when: false + +- name: "Trigger bootstrapped notification: remove `keycloak_quarkus_admin_user[_pass]` env vars" + when: + - not ansible_local.keycloak.general.bootstrapped | default(false) | bool # it was not bootstrapped prior to the current role's execution + - keycloak_service_status.status.ActiveState == "active" # but it is now + ansible.builtin.assert: { that: true, quiet: true } + changed_when: true + notify: + - bootstrapped + +- name: Flush pending handlers + ansible.builtin.meta: flush_handlers diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index 4667596..ef27d27 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -1,6 +1,10 @@ {{ ansible_managed | comment }} +{% if not ansible_local.keycloak.general.bootstrapped | default(false) | bool %} KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' +{% else %} +{{ keycloak.bootstrap_mnemonic }} +{% endif %} PATH={{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }} JAVA_OPTS={{ keycloak_quarkus_java_opts }} diff --git a/roles/keycloak_quarkus/templates/keycloak.fact.j2 b/roles/keycloak_quarkus/templates/keycloak.fact.j2 new file mode 100644 index 0000000..e035110 --- /dev/null +++ b/roles/keycloak_quarkus/templates/keycloak.fact.j2 @@ -0,0 +1,2 @@ +[general] +bootstrapped={{ bootstrapped | lower }} diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index 84fbeaa..fcf82f0 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -15,3 +15,4 @@ keycloak: # noqa var-naming this is an internal dict of interpolated values file: "{{ keycloak_quarkus_home }}/{{ keycloak_quarkus_log_file }}" level: "{{ keycloak_quarkus_log_level }}" format: "{{ keycloak_quarkus_log_format }}" + bootstrap_mnemonic: "# ansible-middleware/keycloak: bootstrapped" From 04bb465992924576186787f5fdc75d147e33c23e Mon Sep 17 00:00:00 2001 From: Deven Phillips Date: Fri, 19 Apr 2024 09:55:08 -0400 Subject: [PATCH 225/376] Added argument specs --- roles/keycloak_quarkus/meta/argument_specs.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 7a74e64..a07b1a9 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -338,6 +338,12 @@ argument_specs: description: > If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy + keycloak_quarkus_hostname_strict_https: + type: "bool" + description: > + By default, Keycloak requires running using TLS/HTTPS. If the service MUST run without TLS/HTTPS, then set + this option to "true" + downstream: options: rhbk_version: From 2925ea8cf1fd897b987bdb74f70c8f8e0d73cf9e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 23 Apr 2024 16:38:04 +0200 Subject: [PATCH 226/376] Add wait_for systemd logic --- molecule/quarkus/converge.yml | 4 ++ molecule/quarkus/prepare.yml | 2 + roles/keycloak_quarkus/README.md | 40 ++++++++++--------- roles/keycloak_quarkus/defaults/main.yml | 7 +++- roles/keycloak_quarkus/handlers/main.yml | 2 +- .../keycloak_quarkus/meta/argument_specs.yml | 20 ++++++++-- roles/keycloak_quarkus/tasks/restart.yml | 1 + .../templates/keycloak.service.j2 | 11 +++-- 8 files changed, 59 insertions(+), 28 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index ea04de2..0d59050 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -15,6 +15,10 @@ keycloak_quarkus_ks_vault_enabled: true keycloak_quarkus_ks_vault_file: "/opt/keycloak/certs/keystore.p12" keycloak_quarkus_ks_vault_pass: keystorepassword + keycloak_quarkus_systemd_wait_for_port: true + keycloak_quarkus_systemd_wait_for_timeout: 20 + keycloak_quarkus_systemd_wait_for_delay: 2 + keycloak_quarkus_systemd_wait_for_log: true roles: - role: keycloak_quarkus - role: keycloak_realm diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index b4f2431..0095226 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -24,7 +24,9 @@ - name: Create vault keystore ansible.builtin.command: keytool -importpass -alias TestRealm_testalias -keystore keystore.p12 -storepass keystorepassword delegate_to: localhost + register: keytool_cmd changed_when: False + failed_when: not 'already exists' in keytool_cmd.stdout and keytool_cmd.rc != 0 - name: Copy certificates and vault become: yes diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index fb41533..5d0641c 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -12,15 +12,16 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| |`keycloak_quarkus_version`| keycloak.org package version | `24.0.3` | +|`keycloak_quarkus_offline_install` | Perform an offline install | `False`| +|`keycloak_quarkus_version`| keycloak.org package version | `23.0.7` | +|`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | +|`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | #### Service configuration | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` | -|`keycloak_quarkus_ha_discovery`| Discovery protocol for HA cluster members | `TCPPING` | -|`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` | |`keycloak_quarkus_admin_user`| Administration console user account | `admin` | |`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | |`keycloak_quarkus_host`| Hostname for the Keycloak server | `localhost` | @@ -29,13 +30,11 @@ Role Defaults |`keycloak_quarkus_http_port`| HTTP listening port | `8080` | |`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` | -|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7800` | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` | |`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` | |`keycloak_quarkus_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` | |`keycloak_quarkus_service_restartsec`| systemd RestartSec | `10s` | -|`keycloak_quarkus_service_pidfile`| Pid file path for service | `/run/keycloak.pid` | |`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | |`keycloak_quarkus_java_heap_opts`| Heap memory JVM setting | `-Xms1024m -Xmx2048m` | @@ -57,8 +56,24 @@ Role Defaults |`keycloak_quarkus_https_trust_store_file`| The file path to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` | |`keycloak_quarkus_https_trust_store_password`| Password for the trust store | `""` | |`keycloak_quarkus_proxy_headers`| Parse reverse proxy headers (`forwarded` or `xforwarded`) | `""` | -|`keycloak_quarkus_config_key_store_file`| Path to the configuration key store; only used if `keycloak_quarkus_keystore_password` is not empty | `{{ keycloak.home }}/conf/conf_store.p12` if `keycloak_quarkus_keystore_password`!='', else '' | -|`keycloak_quarkus_config_key_store_password`| Password of the configuration key store; if non-empty, `keycloak_quarkus_db_pass` will be saved to the key store at `keycloak_quarkus_config_key_store_file` (instead of being written to the configuration file in clear text | `""` | +|`keycloak_quarkus_config_key_store_file`| Path to the configuration key store; only used if `keycloak_quarkus_keystore_password` is not empty | `{{ keycloak.home }}/conf/conf_store.p12` if `keycloak_quarkus_keystore_password != ''`, else `''` | +|`keycloak_quarkus_config_key_store_password`| Password of the configuration keystore; if non-empty, `keycloak_quarkus_db_pass` will be saved to the keystore at `keycloak_quarkus_config_key_store_file` instead of being written to the configuration file in clear text | `""` | +|`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | +|`keycloak_quarkus_configure_iptables` | Ensure iptables is configured for keycloak ports | `False` | + + +#### High-availability + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` | +|`keycloak_quarkus_ha_discovery`| Discovery protocol for HA cluster members | `TCPPING` | +|`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` | +|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7800` | +|`keycloak_quarkus_systemd_wait_for_port` | Whether systemd unit should wait for keycloak port before returning | `{{ keycloak_quarkus_ha_enabled }}` | +|`keycloak_quarkus_systemd_wait_for_log` | Whether systemd unit should wait for service to be up in logs | `false` | +|`keycloak_quarkus_systemd_wait_for_timeout`| How long to wait for service to be alive (seconds) | `60` | +|`keycloak_quarkus_systemd_wait_for_delay`| Activation delay for service systemd unit (seconds) | `10` | #### Hostname configuration @@ -94,17 +109,6 @@ Role Defaults |`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` | -#### Install options - -| Variable | Description | Default | -|:---------|:------------|:---------| -|`keycloak_quarkus_offline_install` | Perform an offline install | `False`| -|`keycloak_quarkus_version`| keycloak.org package version | `23.0.7` | -|`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | -|`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | -|`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | - - #### Miscellaneous configuration | Variable | Description | Default | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index e3e2504..1999dd8 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -16,7 +16,6 @@ keycloak_quarkus_config_dir: "{{ keycloak_quarkus_home }}/conf" keycloak_quarkus_start_dev: false keycloak_quarkus_service_user: keycloak keycloak_quarkus_service_group: keycloak -keycloak_quarkus_service_pidfile: "/run/keycloak/keycloak.pid" keycloak_quarkus_service_restart_always: false keycloak_quarkus_service_restart_on_failure: false keycloak_quarkus_service_restartsec: "10s" @@ -66,7 +65,11 @@ keycloak_quarkus_config_key_store_password: '' keycloak_quarkus_ha_enabled: false keycloak_quarkus_ha_discovery: "TCPPING" ### Enable database configuration, must be enabled when HA is configured -keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False }}" +keycloak_quarkus_db_enabled: "{{ keycloak_quarkus_ha_enabled }}" +keycloak_quarkus_systemd_wait_for_port: "{{ keycloak_quarkus_ha_enabled }}" +keycloak_quarkus_systemd_wait_for_log: false +keycloak_quarkus_systemd_wait_for_timeout: 60 +keycloak_quarkus_systemd_wait_for_delay: 10 ### keycloak frontend url keycloak_quarkus_frontend_url: diff --git a/roles/keycloak_quarkus/handlers/main.yml b/roles/keycloak_quarkus/handlers/main.yml index d6b2220..f60e747 100644 --- a/roles/keycloak_quarkus/handlers/main.yml +++ b/roles/keycloak_quarkus/handlers/main.yml @@ -9,9 +9,9 @@ - name: "Restart {{ keycloak.service_name }}" ansible.builtin.include_tasks: restart.yml listen: "restart keycloak" - - name: "Print deprecation warning" ansible.builtin.fail: msg: "Deprecation warning: you are using the deprecated variable '{{ deprecated_variable | d('NotSet') }}', check docs on how to upgrade." ignore_errors: true + failed_when: false listen: "print deprecation warning" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 5d0519b..460c9a7 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -48,10 +48,6 @@ argument_specs: default: "keycloak" description: "Posix account group" type: "str" - keycloak_quarkus_service_pidfile: - default: "/run/keycloak/keycloak.pid" - description: "Pid file path for service" - type: "str" keycloak_quarkus_configure_firewalld: default: false description: "Ensure firewalld is running and configure keycloak ports" @@ -360,6 +356,22 @@ argument_specs: required: false type: "str" description: "The password for accessing the keystore vault SPI" + keycloak_quarkus_systemd_wait_for_port: + description: 'Whether systemd unit should wait for keycloak port before returning' + default: "{{ keycloak_quarkus_ha_enabled }}" + type: "bool" + keycloak_quarkus_systemd_wait_for_log: + description: 'Whether systemd unit should wait for service to be up in logs' + default: false + type: "bool" + keycloak_quarkus_systemd_wait_for_timeout: + description: "How long to wait for service to be alive (seconds)" + default: 60 + type: 'int' + keycloak_quarkus_systemd_wait_for_delay: + description: "Activation delay for service systemd unit (seconds)" + default: 10 + type: 'int' downstream: options: rhbk_version: diff --git a/roles/keycloak_quarkus/tasks/restart.yml b/roles/keycloak_quarkus/tasks/restart.yml index f709f75..77e1099 100644 --- a/roles/keycloak_quarkus/tasks/restart.yml +++ b/roles/keycloak_quarkus/tasks/restart.yml @@ -1,5 +1,6 @@ --- - name: "Restart and enable {{ keycloak.service_name }} service" + throttle: 1 ansible.builtin.systemd: name: keycloak enabled: true diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 3cdfacf..9cabb69 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -4,9 +4,7 @@ Description=Keycloak Server After=network.target [Service] -Type=simple EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }} -PIDFile={{ keycloak_quarkus_service_pidfile }} {% if keycloak_quarkus_start_dev %} ExecStart={{ keycloak.home }}/bin/kc.sh start-dev {% else %} @@ -14,15 +12,22 @@ ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized {% endif %} User={{ keycloak.service_user }} Group={{ keycloak.service_group }} +SuccessExitStatus=0 143 {% if keycloak_quarkus_service_restart_always %} Restart=always {% elif keycloak_quarkus_service_restart_on_failure %} Restart=on-failure {% endif %} RestartSec={{ keycloak_quarkus_service_restartsec }} -{% if keycloak_quarkus_http_port|int < 1024 or keycloak_quarkus_https_port|int < 1024 %} +{% if keycloak_quarkus_http_port | int < 1024 or keycloak_quarkus_https_port | int < 1024 %} AmbientCapabilities=CAP_NET_BIND_SERVICE {% endif %} +{% if keycloak_quarkus_systemd_wait_for_port %} +ExecStartPost=/usr/bin/timeout {{ keycloak_quarkus_systemd_wait_for_timeout }} sh -c 'while ! ss -H -t -l -n sport = :{{ keycloak_quarkus_https_port }} | grep -q "^LISTEN.*:{{ keycloak_quarkus_https_port }}"; do sleep 1; done && /bin/sleep {{ keycloak_quarkus_systemd_wait_for_delay }}' +{% endif %} +{% if keycloak_quarkus_systemd_wait_for_log %} +ExecStartPost=/usr/bin/timeout {{ keycloak_quarkus_systemd_wait_for_timeout }} sh -c 'cat {{ keycloak.log.file }} | sed "/Profile.*activated/ q" && /bin/sleep {{ keycloak_quarkus_systemd_wait_for_delay }}' +{% endif %} [Install] WantedBy=multi-user.target From 213a9a07665aa3a0e48c801343e6f2b4e3866fe8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 24 Apr 2024 17:56:15 +0200 Subject: [PATCH 227/376] ci: downstream molecule fixes --- molecule/quarkus/prepare.yml | 5 +++++ roles/keycloak_quarkus/README.md | 1 - roles/keycloak_quarkus/tasks/prereqs.yml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 0095226..e3306e5 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -21,6 +21,11 @@ path: "/opt/keycloak/certs/" mode: 0755 + - name: Make sure a jre is available (for keytool to prepare keystore) + ansible.builtin.package: + name: java-17-openjdk-headless + state: present + - name: Create vault keystore ansible.builtin.command: keytool -importpass -alias TestRealm_testalias -keystore keystore.p12 -storepass keystorepassword delegate_to: localhost diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 5d0641c..f1d17fb 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -13,7 +13,6 @@ Role Defaults |:---------|:------------|:--------| |`keycloak_quarkus_version`| keycloak.org package version | `24.0.3` | |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| -|`keycloak_quarkus_version`| keycloak.org package version | `23.0.7` | |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index d96c09e..4f9eec9 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -44,7 +44,7 @@ packages_list: "{{ keycloak_quarkus_prereq_package_list }}" - name: "Validate keytool" - when: keycloak.config_key_store_enabled + when: keycloak_quarkus_config_key_store_password | length > 0 block: - name: "Attempt to run keytool" changed_when: false From 4c056d886eb647a901af5d0e55680c74833bb356 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 24 Apr 2024 21:20:16 +0200 Subject: [PATCH 228/376] ci: downstream molecule fixes --- molecule/quarkus/prepare.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index e3306e5..1601a79 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -15,7 +15,7 @@ changed_when: False - name: Create conf directory # risky-file-permissions in test user account does not exist yet - become: yes + become: true ansible.builtin.file: state: directory path: "/opt/keycloak/certs/" @@ -25,6 +25,7 @@ ansible.builtin.package: name: java-17-openjdk-headless state: present + become: true - name: Create vault keystore ansible.builtin.command: keytool -importpass -alias TestRealm_testalias -keystore keystore.p12 -storepass keystorepassword @@ -34,7 +35,7 @@ failed_when: not 'already exists' in keytool_cmd.stdout and keytool_cmd.rc != 0 - name: Copy certificates and vault - become: yes + become: true ansible.builtin.copy: src: "{{ item }}" dest: "/opt/keycloak/certs/{{ item }}" From ac23e04d6ad053e0fcef7b9bf8b6d22ba0bfc69b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 25 Apr 2024 08:16:56 +0200 Subject: [PATCH 229/376] ci: downstream molecule fixes --- roles/keycloak_quarkus/tasks/main.yml | 33 ++++++--------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 4c0db72..2dadf61 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -32,29 +32,6 @@ tags: - install -- name: "Configure config for keycloak service" - ansible.builtin.template: - src: keycloak.conf.j2 - dest: "{{ keycloak.home }}/conf/keycloak.conf" - owner: "{{ keycloak.service_user }}" - group: "{{ keycloak.service_group }}" - mode: '0640' - become: true - notify: - - rebuild keycloak config - - restart keycloak - -- name: "Configure quarkus config for keycloak service" - ansible.builtin.template: - src: quarkus.properties.j2 - dest: "{{ keycloak.home }}/conf/quarkus.properties" - owner: "{{ keycloak.service_user }}" - group: "{{ keycloak.service_group }}" - mode: '0640' - become: true - notify: - - restart keycloak - - name: Create tcpping cluster node list ansible.builtin.set_fact: keycloak_quarkus_cluster_nodes: > @@ -69,14 +46,18 @@ loop: "{{ ansible_play_batch }}" when: keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING' -- name: "Configure infinispan config for keycloak service" +- name: "Configure config files for keycloak service" ansible.builtin.template: - src: cache-ispn.xml.j2 - dest: "{{ keycloak.home }}/conf/cache-ispn.xml" + src: "{{ item }}.j2" + dest: "{{ keycloak.home }}/conf/{{ item }}" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: '0640' become: true + loop: + - keycloak.conf + - quarkus.properties + - cache-ispn.xml notify: - rebuild keycloak config - restart keycloak From 6967385c7fa8c2bede1db4e4f846369aee384a78 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 25 Apr 2024 13:03:03 +0200 Subject: [PATCH 230/376] ci: downstream molecule fixes --- molecule/quarkus/prepare.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 1601a79..28b42c6 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -22,10 +22,14 @@ mode: 0755 - name: Make sure a jre is available (for keytool to prepare keystore) + delegate_to: localhost ansible.builtin.package: - name: java-17-openjdk-headless + name: + - java-17-openjdk-headless + - openjdk-17-jdk-headless state: present become: true + failed_when: false - name: Create vault keystore ansible.builtin.command: keytool -importpass -alias TestRealm_testalias -keystore keystore.p12 -storepass keystorepassword From 278a70d62768e245e3df4a4feafdb9a3ce326e88 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 25 Apr 2024 13:57:31 +0200 Subject: [PATCH 231/376] ci: downstream molecule fixes --- molecule/quarkus/prepare.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 28b42c6..1efdb15 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -24,9 +24,7 @@ - name: Make sure a jre is available (for keytool to prepare keystore) delegate_to: localhost ansible.builtin.package: - name: - - java-17-openjdk-headless - - openjdk-17-jdk-headless + name: "{{ 'java-17-openjdk-headless' if hera_home | length > 0 else 'openjdk-17-jdk-headless' }}" state: present become: true failed_when: false From a33393a477844ecb8b27303c9b175990f914f431 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 25 Apr 2024 14:11:05 +0200 Subject: [PATCH 232/376] ci: downstream molecule fixes --- molecule/quarkus/verify.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 1efe9dd..dd8490f 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -53,7 +53,7 @@ fail_msg: "Service log symlink not correctly created" - name: Check log file - become: yes + become: true ansible.builtin.stat: path: /tmp/keycloak/keycloak.log register: keycloak_log_file @@ -77,6 +77,7 @@ - not keycloak_default_log_folder.stat.exists - name: Verify vault SPI in logfile + become: true ansible.builtin.shell: | set -o pipefail zgrep 'Configured KeystoreVaultProviderFactory with the keystore file' /opt/keycloak/keycloak-*/data/log/keycloak.log*zip From 43b9ffcb6486cd881394b00f4d7f333840093b48 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 30 Apr 2024 10:45:20 +0200 Subject: [PATCH 233/376] Providers config and custom providers --- molecule/quarkus/converge.yml | 10 +++++++ roles/keycloak_quarkus/README.md | 27 +++++++++++++++++++ roles/keycloak_quarkus/defaults/main.yml | 2 ++ .../keycloak_quarkus/meta/argument_specs.yml | 4 +++ roles/keycloak_quarkus/tasks/install.yml | 12 +++++++++ roles/keycloak_quarkus/tasks/prereqs.yml | 9 +++++++ .../templates/keycloak.conf.j2 | 11 ++++++++ 7 files changed, 75 insertions(+) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 0d59050..0480f9a 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -19,6 +19,16 @@ keycloak_quarkus_systemd_wait_for_timeout: 20 keycloak_quarkus_systemd_wait_for_delay: 2 keycloak_quarkus_systemd_wait_for_log: true + keycloak_quarkus_providers: + - id: http-client + spi: connections + default: true + restart: true + properties: + - key: default-connection-pool-size + value: 10 + - id: spid-saml + url: https://github.com/italia/spid-keycloak-provider/releases/download/24.0.2/spid-provider.jar roles: - role: keycloak_quarkus - role: keycloak_realm diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index f1d17fb..ed44e21 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -145,6 +145,33 @@ Role Defaults |`keycloak_quarkus_ks_vault_type`| Type of the keystore used for the vault SPI | `PKCS12` | +#### Configuring providers + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_providers`| List of provider definitions; see below | `[]` | + +Provider definition: + +```yaml +keycloak_quarkus_providers: + - id: http-client # required + spi: connections # required if url is not specified + default: true # optional, whether to set default for spi, default false + restart: true # optional, whether to restart, default true + url: https://.../.../custom_spi.jar # optional, url for download + properties: # optional, list of key-values + - key: default-connection-pool-size + value: 10 +``` + +the definition above will generate the following build command: + +``` +bin/kc.sh build --spi-connections-provider=http-client --spi-connections-http-client-default-connection-pool-size=10 +``` + + Role Variables -------------- diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 1999dd8..771dc85 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -144,3 +144,5 @@ keycloak_quarkus_ks_vault_enabled: false keycloak_quarkus_ks_vault_file: "{{ keycloak_quarkus_config_dir }}/keystore.p12" keycloak_quarkus_ks_vault_type: PKCS12 keycloak_quarkus_ks_vault_pass: + +keycloak_quarkus_providers: [] diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 460c9a7..7d97e29 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -372,6 +372,10 @@ argument_specs: description: "Activation delay for service systemd unit (seconds)" default: 10 type: 'int' + keycloak_quarkus_providers: + description: "List of provider definition dicts: { 'id': str, 'spi': str, 'url': str, 'default': bool, 'properties': list of key/value }" + default: [] + type: "list" downstream: options: rhbk_version: diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 085f3d7..d95887f 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -164,3 +164,15 @@ when: - rhbk_enable is defined and rhbk_enable - keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url is defined + +- name: "Download custom providers" + ansible.builtin.get_url: + url: "{{ item.url }}" + dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: '0640' + become: true + loop: "{{ keycloak_quarkus_providers }}" + when: item.url is defined and item.url | length > 0 + notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or not item.restart else [] }}" diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 4f9eec9..e0a76d5 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -56,3 +56,12 @@ when: keytool_check.rc != 0 ansible.builtin.fail: msg: "keytool NOT found in the PATH, but is required for setting up the configuration key store" + +- name: "Validate providers" + ansible.builtin.assert: + that: + - item.id is defined and item.id | length > 0 + - (item.spi is defined and item.spi | length > 0) or (item.url is defined and item.url | length > 0) + quiet: true + fail_msg: "Providers definition is incorrect; `id` and one of `spi` or `url` are mandatory. `key` and `value` are mandatory for each property" + loop: "{{ keycloak_quarkus_providers }}" diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 065eea7..f55ee80 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -97,3 +97,14 @@ vault-file={{ keycloak_quarkus_ks_vault_file }} vault-type={{ keycloak_quarkus_ks_vault_type }} vault-pass={{ keycloak_quarkus_ks_vault_pass }} {% endif %} + + +# Providers +{% for provider in keycloak_quarkus_providers %} +{% if provider.default is defined and provider.default %} +spi-{{ provider.spi }}-provider={{ provider.id }} +{% endif %} +{% if provider.properties is defined %}{% for property in provider.properties %} +spi-{{ provider.spi }}-{{ provider.id }}-{{ property.key }}={{ property.value }} +{% endfor %}{% endif %} +{% endfor %} From eafc4586d67ff356c8f42bd63b3ad90656831d98 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 30 Apr 2024 13:09:27 +0200 Subject: [PATCH 234/376] ci: turn historicized docs off --- .github/workflows/docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c1a95bf..540fe4f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -15,3 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' collection_fqcn: 'middleware_automation.keycloak' + historical_docs: 'false' From a7b9f0ef97132f0e9e5c1dfa77bb6267cdd80d47 Mon Sep 17 00:00:00 2001 From: Deven Phillips Date: Tue, 30 Apr 2024 14:27:42 -0400 Subject: [PATCH 235/376] Add option to override JDBC download parameters --- roles/keycloak_quarkus/meta/argument_specs.yml | 9 +++++++++ roles/keycloak_quarkus/tasks/jdbc_driver.yml | 13 +++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 460c9a7..c1ebe8f 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -372,6 +372,15 @@ argument_specs: description: "Activation delay for service systemd unit (seconds)" default: 10 type: 'int' + keycloak_quarkus_jdbc_download_url: + description: "Override the default Maven Central download URL for the JDBC driver" + type: "str" + keycloak_quarkus_jdbc_download_user: + description: "Set a username with which to authenticate when downloading JDBC drivers from an alternative location" + type: "str" + keycloak_quarkus_jdbc_download_pass: + description: "Set a password with which to authenticate when downloading JDBC drivers from an alternative location (requires keycloak_quarkus_jdbc_download_user)" + type: "str" downstream: options: rhbk_version: diff --git a/roles/keycloak_quarkus/tasks/jdbc_driver.yml b/roles/keycloak_quarkus/tasks/jdbc_driver.yml index 310509a..bcb7069 100644 --- a/roles/keycloak_quarkus/tasks/jdbc_driver.yml +++ b/roles/keycloak_quarkus/tasks/jdbc_driver.yml @@ -1,10 +1,19 @@ --- -- name: "Retrieve JDBC Driver from {{ keycloak_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url }}" +- name: Verify valid parameters for download credentials when specified + fail: + msg: >- + When JDBC driver download credentials are set, both the username and the password MUST be set + when: + - keycloak_jdbc_download_user is undefined and keycloak_jdbc_download_pass is not undefined + - keycloak_jdbc_download_pass is undefined and keycloak_jdbc_download_user is not undefined +- name: "Retrieve JDBC Driver from {{ keycloak_jdbc_download_user | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" ansible.builtin.get_url: - url: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url }}" + url: "{{ keycloak_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" dest: "{{ keycloak.home }}/providers" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" + url_username: "{{ keycloak_jdbc_download_user | default(omit) }}" + url_password: "{{ keycloak_jdbc_download_pass | default(omit) }}" mode: '0640' become: true notify: From c2904bf20d24c9d17b974e5061c39369a3f5e604 Mon Sep 17 00:00:00 2001 From: Deven Phillips Date: Tue, 30 Apr 2024 14:48:10 -0400 Subject: [PATCH 236/376] Use FQCN for fail module --- roles/keycloak_quarkus/tasks/jdbc_driver.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/tasks/jdbc_driver.yml b/roles/keycloak_quarkus/tasks/jdbc_driver.yml index bcb7069..11fa385 100644 --- a/roles/keycloak_quarkus/tasks/jdbc_driver.yml +++ b/roles/keycloak_quarkus/tasks/jdbc_driver.yml @@ -1,6 +1,6 @@ --- -- name: Verify valid parameters for download credentials when specified - fail: +- name: "Verify valid parameters for download credentials when specified" + ansible.builtin.fail: msg: >- When JDBC driver download credentials are set, both the username and the password MUST be set when: From 55f6881b2f1e909a5b5b42431cd1f1fbd6588258 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 1 May 2024 14:44:01 +0000 Subject: [PATCH 237/376] Update changelog for release 2.2.0 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 21 +++++++++++++++++++-- changelogs/changelog.yaml | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 89d0992..4366622 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,25 @@ middleware\_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.2.0 +====== + +Major Changes +------------- + +- Support java keystore for configuration of sensitive options `#189 `_ + +Minor Changes +------------- + +- Add ``wait_for_port`` and ``wait_for_log`` systemd unit logic `#199 `_ +- Customize jdbc driver downloads, optional authentication `#202 `_ +- Keystore-based vault SPI configuration `#196 `_ +- New ``keycloak_quarkus_hostname_strict_https`` parameter `#195 `_ +- Providers config and custom providers `#201 `_ +- Remove administrator credentials from files once keycloak is bootstrapped `#197 `_ +- Update keycloak to 24.0 `#194 `_ + v2.1.2 ====== @@ -14,7 +33,6 @@ Release Summary Internal release, documentation or test changes only. - v2.1.1 ====== @@ -286,7 +304,6 @@ Release Summary Internal release, documentation or test changes only. - v1.0.3 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 3fd8b1b..a58a5d6 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -464,3 +464,42 @@ releases: ' release_date: '2024-04-17' + 2.2.0: + changes: + major_changes: + - 'Support java keystore for configuration of sensitive options `#189 `_ + + ' + minor_changes: + - 'Add ``wait_for_port`` and ``wait_for_log`` systemd unit logic `#199 `_ + + ' + - 'Customize jdbc driver downloads, optional authentication `#202 `_ + + ' + - 'Keystore-based vault SPI configuration `#196 `_ + + ' + - 'New ``keycloak_quarkus_hostname_strict_https`` parameter `#195 `_ + + ' + - 'Providers config and custom providers `#201 `_ + + ' + - 'Remove administrator credentials from files once keycloak is bootstrapped + `#197 `_ + + ' + - 'Update keycloak to 24.0 `#194 `_ + + ' + fragments: + - 189.yaml + - 194.yaml + - 195.yaml + - 196.yaml + - 197.yaml + - 199.yaml + - 201.yaml + - 202.yaml + release_date: '2024-05-01' From 9e6a6f607612bf4585eccf022ff9f3f7559caa8d Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 1 May 2024 14:44:15 +0000 Subject: [PATCH 238/376] Bump version to 2.2.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 02838e3..d121f3c 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.2.0" +version: "2.2.1" readme: README.md authors: - Romain Pelisse From 1a73c39a9140c7e0132e0211e3726191b61075d9 Mon Sep 17 00:00:00 2001 From: Deven Phillips Date: Thu, 2 May 2024 12:09:36 -0400 Subject: [PATCH 239/376] Fix logic in when clause --- roles/keycloak_quarkus/tasks/jdbc_driver.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/tasks/jdbc_driver.yml b/roles/keycloak_quarkus/tasks/jdbc_driver.yml index 11fa385..10731cf 100644 --- a/roles/keycloak_quarkus/tasks/jdbc_driver.yml +++ b/roles/keycloak_quarkus/tasks/jdbc_driver.yml @@ -4,8 +4,7 @@ msg: >- When JDBC driver download credentials are set, both the username and the password MUST be set when: - - keycloak_jdbc_download_user is undefined and keycloak_jdbc_download_pass is not undefined - - keycloak_jdbc_download_pass is undefined and keycloak_jdbc_download_user is not undefined + - (keycloak_jdbc_download_user is undefined and keycloak_jdbc_download_pass is not undefined) or (keycloak_jdbc_download_pass is undefined and keycloak_jdbc_download_user is not undefined) - name: "Retrieve JDBC Driver from {{ keycloak_jdbc_download_user | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" ansible.builtin.get_url: url: "{{ keycloak_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" From 978494524fd850f396245c4302a2f5eb5eb24f67 Mon Sep 17 00:00:00 2001 From: Deven Phillips Date: Thu, 2 May 2024 12:31:16 -0400 Subject: [PATCH 240/376] Fix errors introduced --- roles/keycloak_quarkus/tasks/jdbc_driver.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_quarkus/tasks/jdbc_driver.yml b/roles/keycloak_quarkus/tasks/jdbc_driver.yml index 10731cf..dc84880 100644 --- a/roles/keycloak_quarkus/tasks/jdbc_driver.yml +++ b/roles/keycloak_quarkus/tasks/jdbc_driver.yml @@ -3,8 +3,8 @@ ansible.builtin.fail: msg: >- When JDBC driver download credentials are set, both the username and the password MUST be set - when: - - (keycloak_jdbc_download_user is undefined and keycloak_jdbc_download_pass is not undefined) or (keycloak_jdbc_download_pass is undefined and keycloak_jdbc_download_user is not undefined) + when: + - (keycloak_jdbc_download_user is undefined and keycloak_jdbc_download_pass is not undefined) or (keycloak_jdbc_download_pass is undefined and keycloak_jdbc_download_user is not undefined) - name: "Retrieve JDBC Driver from {{ keycloak_jdbc_download_user | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" ansible.builtin.get_url: url: "{{ keycloak_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" From 1ab3ebc2a4dfdf54cc4fc19f091a58d31af1fd89 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Thu, 2 May 2024 16:59:47 +0000 Subject: [PATCH 241/376] Update changelog for release 2.2.1 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 13 +++++++++++++ changelogs/changelog.yaml | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4366622..145a090 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,19 @@ middleware\_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.2.1 +====== + +Release Summary +--------------- + +Internal release, documentation or test changes only. + +Bugfixes +-------- + +- JDBC provider: fix clause in argument validation `#204 `_ + v2.2.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index a58a5d6..400d633 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -503,3 +503,14 @@ releases: - 201.yaml - 202.yaml release_date: '2024-05-01' + 2.2.1: + changes: + bugfixes: + - 'JDBC provider: fix clause in argument validation `#204 `_ + + ' + release_summary: Internal release, documentation or test changes only. + fragments: + - 204.yaml + - v2.2.1-devel_summary.yaml + release_date: '2024-05-02' From 1d6a6eb7ee2449f41528d30d2ff4eed0c7ae98d2 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Thu, 2 May 2024 17:00:01 +0000 Subject: [PATCH 242/376] Bump version to 2.2.2 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index d121f3c..ae08f9b 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.2.1" +version: "2.2.2" readme: README.md authors: - Romain Pelisse From b14d75dfab246ed38f97158c98aeb014f691a6e3 Mon Sep 17 00:00:00 2001 From: Deven Phillips Date: Thu, 2 May 2024 14:33:36 -0400 Subject: [PATCH 243/376] jdbc_download and validate_certs params update - Added jdbc_download customization to both keycloak releases - Added option to allow invalid certificates to download JDBC drivers --- github.json | 0 roles/keycloak/meta/argument_specs.yml | 13 +++++++++++++ roles/keycloak/tasks/jdbc_driver.yml | 9 +++++++++ roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/tasks/jdbc_driver.yml | 9 +++++---- 5 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 github.json diff --git a/github.json b/github.json new file mode 100644 index 0000000..e69de29 diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index 7ba6509..eab89cf 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -316,6 +316,19 @@ argument_specs: default: '/var/log/keycloak' type: "str" description: "Set the destination of the keycloak log folder link" + keycloak_jdbc_download_url: + description: "Override the default Maven Central download URL for the JDBC driver" + type: "str" + keycloak_jdbc_download_user: + description: "Set a username with which to authenticate when downloading JDBC drivers from an alternative location" + type: "str" + keycloak_jdbc_download_pass: + description: "Set a password with which to authenticate when downloading JDBC drivers from an alternative location (requires keycloak_jdbc_download_user)" + type: "str" + keycloak_jdbc_download_validate_certs: + default: true + description: "Allow the option to ignore invalid certificates when downloading JDBC drivers from a custom URL" + type: "bool" downstream: options: sso_version: diff --git a/roles/keycloak/tasks/jdbc_driver.yml b/roles/keycloak/tasks/jdbc_driver.yml index 1b0a1ec..a7cd8ab 100644 --- a/roles/keycloak/tasks/jdbc_driver.yml +++ b/roles/keycloak/tasks/jdbc_driver.yml @@ -16,6 +16,12 @@ become: true when: - not dest_path.stat.exists +- name: "Verify valid parameters for download credentials when specified" + ansible.builtin.fail: + msg: >- + When JDBC driver download credentials are set, both the username and the password MUST be set + when: + - (keycloak_jdbc_download_user is undefined and keycloak_jdbc_download_pass is not undefined) or (keycloak_jdbc_download_pass is undefined and keycloak_jdbc_download_user is not undefined) - name: "Retrieve JDBC Driver from {{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_url }}" ansible.builtin.get_url: @@ -23,6 +29,9 @@ dest: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}/{{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_filename }}" group: "{{ keycloak_service_group }}" owner: "{{ keycloak_service_user }}" + url_username: "{{ keycloak_jdbc_download_user | default(omit) }}" + url_password: "{{ keycloak_jdbc_download_pass | default(omit) }}" + validate_certs: "{{ keycloak_jdbc_download_validate_certs | default(omit) }}" mode: 0640 become: true diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 0669dc5..538e0ab 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -385,6 +385,10 @@ argument_specs: keycloak_quarkus_jdbc_download_pass: description: "Set a password with which to authenticate when downloading JDBC drivers from an alternative location (requires keycloak_quarkus_jdbc_download_user)" type: "str" + keycloak_quarkus_jdbc_download_validate_certs: + default: true + description: "Allow the option to ignore invalid certificates when downloading JDBC drivers from a custom URL" + type: "bool" downstream: options: rhbk_version: diff --git a/roles/keycloak_quarkus/tasks/jdbc_driver.yml b/roles/keycloak_quarkus/tasks/jdbc_driver.yml index dc84880..52298aa 100644 --- a/roles/keycloak_quarkus/tasks/jdbc_driver.yml +++ b/roles/keycloak_quarkus/tasks/jdbc_driver.yml @@ -4,15 +4,16 @@ msg: >- When JDBC driver download credentials are set, both the username and the password MUST be set when: - - (keycloak_jdbc_download_user is undefined and keycloak_jdbc_download_pass is not undefined) or (keycloak_jdbc_download_pass is undefined and keycloak_jdbc_download_user is not undefined) + - (keycloak_quarkus_jdbc_download_user is undefined and keycloak_quarkus_jdbc_download_pass is not undefined) or (keycloak_quarkus_jdbc_download_pass is undefined and keycloak_quarkus_jdbc_download_user is not undefined) - name: "Retrieve JDBC Driver from {{ keycloak_jdbc_download_user | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" ansible.builtin.get_url: - url: "{{ keycloak_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" + url: "{{ keycloak_quarkus_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" dest: "{{ keycloak.home }}/providers" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - url_username: "{{ keycloak_jdbc_download_user | default(omit) }}" - url_password: "{{ keycloak_jdbc_download_pass | default(omit) }}" + url_username: "{{ keycloak_quarkus_jdbc_download_user | default(omit) }}" + url_password: "{{ keycloak_quarkus_jdbc_download_pass | default(omit) }}" + validate_certs: "{{ keycloak_quarkus_jdbc_download_validate_certs | default(omit) }}" mode: '0640' become: true notify: From feec4d9f8b866150f759ae7eb9c9ace87df2ab4a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 3 May 2024 13:03:18 +0200 Subject: [PATCH 244/376] controller priv escalation --- roles/keycloak_quarkus/tasks/install.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index d95887f..7155c3a 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -57,6 +57,7 @@ path: "{{ lookup('env', 'PWD') }}" register: local_path delegate_to: localhost + run_once: true become: false - name: Download keycloak archive @@ -108,15 +109,20 @@ client_secret: "{{ rhn_password }}" product_id: "{{ (rhn_filtered_products | first).id }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" + mode: '0640' + owner: "{{ lookup('env', 'USER') | default(omit) }}" no_log: "{{ omit_rhn_output | default(true) }}" delegate_to: localhost run_once: true + become: false - name: Check downloaded archive ansible.builtin.stat: path: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" register: local_archive_path delegate_to: localhost + become: false + run_once: true ## copy and unpack - name: Copy archive to target nodes From 9bc1ae69e9a8af0c720b910197a818f365c2e84f Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Fri, 3 May 2024 14:34:57 +0000 Subject: [PATCH 245/376] Enable copying of key material This commit updates the configuration to use the standard Red Hat Enterprise Linux (RHEL) default path for TLS certificates, which is /etc/pki/tls. Also, it copies the private key and certificate to the target host. --- roles/keycloak_quarkus/README.md | 8 ++++-- roles/keycloak_quarkus/defaults/main.yml | 8 ++++-- .../keycloak_quarkus/meta/argument_specs.yml | 20 ++++++++++++-- roles/keycloak_quarkus/tasks/install.yml | 26 +++++++++++++++++++ 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index ed44e21..17f2bc8 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -44,8 +44,12 @@ Role Defaults |`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | |`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` | -|`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `{{ keycloak.home }}/conf/server.key.pem` | -|`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `{{ keycloak.home }}/conf/server.crt.pem` | +|`keycloak_quarkus_key_file_copy_enabled`| Enable copy of key file to target host | `False` | +|`keycloak_quarkus_key_file_src`| Set the source file path | `""` | +|`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `/etc/pki/tls/private/server.key.pem` | +|`keycloak_quarkus_cert_file_copy_enabled`| Enable copy of cert file to target host | `False`| +|`keycloak_quarkus_cert_file_src`| Set the source file path | `""` | +|`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `/etc/pki/tls/certs/server.crt.pem` | |`keycloak_quarkus_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` | |`keycloak_quarkus_key_store_file`| Deprecated, use `keycloak_quarkus_https_key_store_file` instead. || |`keycloak_quarkus_key_store_password`| Deprecated, use `keycloak_quarkus_https_key_store_password` instead.|| diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 771dc85..fcd02a5 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -47,8 +47,12 @@ keycloak_quarkus_java_opts: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak ### TLS/HTTPS configuration keycloak_quarkus_https_key_file_enabled: false -keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/server.key.pem" -keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/server.crt.pem" +keycloak_quarkus_key_file_copy_enabled: false +keycloak_quarkus_key_file_src: "" +keycloak_quarkus_key_file: "/etc/pki/tls/private/server.key.pem" +keycloak_quarkus_cert_file_copy_enabled: false +keycloak_quarkus_cert_file_src: "" +keycloak_quarkus_cert_file: "/etc/pki/tls/certs/server.crt.pem" #### key store configuration keycloak_quarkus_https_key_store_enabled: false keycloak_quarkus_https_key_store_file: "{{ keycloak.home }}/conf/key_store.p12" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 538e0ab..768b3e9 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -108,12 +108,28 @@ argument_specs: default: false description: "Enable configuration of HTTPS via files in PEM format" type: "bool" + keycloak_quarkus_key_file_copy_enabled: + default: false + description: "Enable copy of key file to target host" + type: "bool" + keycloak_quarkus_key_file_src: + default: "" + description: "Set the source file path" + type: "str" keycloak_quarkus_key_file: - default: "{{ keycloak.home }}/conf/server.key.pem" + default: "/etc/pki/tls/private/server.key.pem" description: "The file path to a private key in PEM format" type: "str" + keycloak_quarkus_cert_file_copy_enabled: + default: false + description: "Enable copy of cert file to target host" + type: "bool" + keycloak_quarkus_cert_file_src: + default: "" + description: "Set the source file path" + type: "str" keycloak_quarkus_cert_file: - default: "{{ keycloak.home }}/conf/server.crt.pem" + default: "/etc/pki/tls/certs/server.crt.pem" description: "The file path to a server certificate or certificate chain in PEM format" type: "str" keycloak_quarkus_https_key_store_enabled: diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index d95887f..b4b566a 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -159,6 +159,32 @@ when: - (not new_version_downloaded.changed) and path_to_workdir.stat.exists +- name: "Copy private key to target" + ansible.builtin.copy: + src: "{{ keycloak_quarkus_key_file_src }}" + dest: "{{ keycloak_quarkus_key_file }}" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: 0640 + become: true + when: + - keycloak_quarkus_https_key_file_enabled is defined and keycloak_quarkus_https_key_file_enabled + - keycloak_quarkus_key_file_copy_enabled is defined and keycloak_quarkus_key_file_copy_enabled + - keycloak_quarkus_key_file_src | length > 0 + +- name: "Copy certificate to target" + ansible.builtin.copy: + src: "{{ keycloak_quarkus_cert_file_src }}" + dest: "{{ keycloak_quarkus_cert_file }}" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: 0644 + become: true + when: + - keycloak_quarkus_https_key_file_enabled is defined and keycloak_quarkus_https_key_file_enabled + - keycloak_quarkus_cert_file_copy_enabled is defined and keycloak_quarkus_cert_file_copy_enabled + - keycloak_quarkus_cert_file_src | length > 0 + - name: "Install {{ keycloak_quarkus_jdbc_engine }} JDBC driver" ansible.builtin.include_tasks: jdbc_driver.yml when: From 7141e1c9b2d53469ddfebb5cf24ef6a740bca64c Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Sun, 5 May 2024 12:08:14 +0200 Subject: [PATCH 246/376] Test: Installation of key material via Ansible role --- molecule/quarkus/converge.yml | 8 +++++--- molecule/quarkus/prepare.yml | 12 ++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 0480f9a..5971a93 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -9,11 +9,13 @@ keycloak_quarkus_log: file keycloak_quarkus_log_level: debug keycloak_quarkus_https_key_file_enabled: true - keycloak_quarkus_key_file: "/opt/keycloak/certs/key.pem" - keycloak_quarkus_cert_file: "/opt/keycloak/certs/cert.pem" + keycloak_quarkus_key_file_copy_enabled: true + keycloak_quarkus_key_file_src: key.pem + keycloak_quarkus_cert_file_copy_enabled: true + keycloak_quarkus_cert_file_src: cert.pem keycloak_quarkus_log_target: /tmp/keycloak keycloak_quarkus_ks_vault_enabled: true - keycloak_quarkus_ks_vault_file: "/opt/keycloak/certs/keystore.p12" + keycloak_quarkus_ks_vault_file: "/opt/keycloak/vault/keystore.p12" keycloak_quarkus_ks_vault_pass: keystorepassword keycloak_quarkus_systemd_wait_for_port: true keycloak_quarkus_systemd_wait_for_timeout: 20 diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 1efdb15..459bafa 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -14,11 +14,11 @@ delegate_to: localhost changed_when: False - - name: Create conf directory # risky-file-permissions in test user account does not exist yet + - name: Create vault directory become: true ansible.builtin.file: state: directory - path: "/opt/keycloak/certs/" + path: "/opt/keycloak/vault" mode: 0755 - name: Make sure a jre is available (for keytool to prepare keystore) @@ -39,10 +39,6 @@ - name: Copy certificates and vault become: true ansible.builtin.copy: - src: "{{ item }}" - dest: "/opt/keycloak/certs/{{ item }}" + src: keystore.p12 + dest: /opt/keycloak/vault/keystore.p12 mode: 0444 - loop: - - cert.pem - - key.pem - - keystore.p12 From 320a5f0d9a171aeb9dbe4bf6914dcedd42596d07 Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Sun, 5 May 2024 11:58:19 +0000 Subject: [PATCH 247/376] Copy the TLS private key from memory This change should avoid storing plain private keys on disk due to security risks. It also makes it easier to encrypt the data with SOPS. --- molecule/quarkus/converge.yml | 2 +- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++-- roles/keycloak_quarkus/tasks/install.yml | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 5971a93..9e74aa6 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -10,7 +10,7 @@ keycloak_quarkus_log_level: debug keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_key_file_copy_enabled: true - keycloak_quarkus_key_file_src: key.pem + keycloak_quarkus_key_content: "{{ lookup('file', 'key.pem') }}" keycloak_quarkus_cert_file_copy_enabled: true keycloak_quarkus_cert_file_src: cert.pem keycloak_quarkus_log_target: /tmp/keycloak diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 17f2bc8..ccb9e75 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -45,7 +45,7 @@ Role Defaults |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | |`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` | |`keycloak_quarkus_key_file_copy_enabled`| Enable copy of key file to target host | `False` | -|`keycloak_quarkus_key_file_src`| Set the source file path | `""` | +|`keycloak_quarkus_key_content`| Content of the TLS private key. Use `"{{ lookup('file', 'server.key.pem') }}"` to lookup a file. | `""` | |`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `/etc/pki/tls/private/server.key.pem` | |`keycloak_quarkus_cert_file_copy_enabled`| Enable copy of cert file to target host | `False`| |`keycloak_quarkus_cert_file_src`| Set the source file path | `""` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index fcd02a5..a54e6c7 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -48,7 +48,7 @@ keycloak_quarkus_java_opts: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak ### TLS/HTTPS configuration keycloak_quarkus_https_key_file_enabled: false keycloak_quarkus_key_file_copy_enabled: false -keycloak_quarkus_key_file_src: "" +keycloak_quarkus_key_content: "" keycloak_quarkus_key_file: "/etc/pki/tls/private/server.key.pem" keycloak_quarkus_cert_file_copy_enabled: false keycloak_quarkus_cert_file_src: "" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 768b3e9..094a46b 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -112,9 +112,9 @@ argument_specs: default: false description: "Enable copy of key file to target host" type: "bool" - keycloak_quarkus_key_file_src: + keycloak_quarkus_key_content: default: "" - description: "Set the source file path" + description: "Content of the TLS private key" type: "str" keycloak_quarkus_key_file: default: "/etc/pki/tls/private/server.key.pem" diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index b4b566a..5a385e2 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -161,7 +161,7 @@ - name: "Copy private key to target" ansible.builtin.copy: - src: "{{ keycloak_quarkus_key_file_src }}" + content: "{{ keycloak_quarkus_key_content }}" dest: "{{ keycloak_quarkus_key_file }}" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" @@ -170,7 +170,7 @@ when: - keycloak_quarkus_https_key_file_enabled is defined and keycloak_quarkus_https_key_file_enabled - keycloak_quarkus_key_file_copy_enabled is defined and keycloak_quarkus_key_file_copy_enabled - - keycloak_quarkus_key_file_src | length > 0 + - keycloak_quarkus_key_content | length > 0 - name: "Copy certificate to target" ansible.builtin.copy: From b427cb8a24624bf83d95c1a417bb20691f7df7c9 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Mon, 6 May 2024 08:11:11 +0000 Subject: [PATCH 248/376] Update changelog for release 2.2.2 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 14 ++++++++++++++ changelogs/changelog.yaml | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 145a090..3d0f005 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,20 @@ middleware\_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.2.2 +====== + +Minor Changes +------------- + +- Copying of key material for TLS configuration `#210 `_ +- Validate certs parameter for JDBC driver downloads `#207 `_ + +Bugfixes +-------- + +- Turn off controller privilege escalation `#209 `_ + v2.2.1 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 400d633..fe5c499 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -514,3 +514,21 @@ releases: - 204.yaml - v2.2.1-devel_summary.yaml release_date: '2024-05-02' + 2.2.2: + changes: + bugfixes: + - 'Turn off controller privilege escalation `#209 `_ + + ' + minor_changes: + - 'Copying of key material for TLS configuration `#210 `_ + + ' + - 'Validate certs parameter for JDBC driver downloads `#207 `_ + + ' + fragments: + - 207.yaml + - 209.yaml + - 210.yaml + release_date: '2024-05-06' From 4da0e83ae92ff21c95c5094158c469f9d23b3f2f Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Mon, 6 May 2024 08:11:28 +0000 Subject: [PATCH 249/376] Bump version to 2.2.3 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index ae08f9b..1e6fd20 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.2.2" +version: "2.2.3" readme: README.md authors: - Romain Pelisse From 2a7395c444df8fcd6af8aa1edf851de5e18f50b1 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 6 May 2024 11:20:00 +0200 Subject: [PATCH 250/376] downstream: update default to rhbk 24.0.3 --- galaxy.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index 1e6fd20..ae08f9b 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.2.3" +version: "2.2.2" readme: README.md authors: - Romain Pelisse diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 094a46b..5fccedc 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -408,7 +408,7 @@ argument_specs: downstream: options: rhbk_version: - default: "22.0.10" + default: "24.0.3" description: "Red Hat Build of Keycloak version" type: "str" rhbk_archive: From 70834ccf133e4c73375daf1ed6c39cf1fbf116d0 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 6 May 2024 12:03:44 +0200 Subject: [PATCH 251/376] downstream: remove problematic owner of downloaded zipfile --- roles/keycloak_quarkus/tasks/install.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index bbface7..732e5b1 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -110,7 +110,6 @@ product_id: "{{ (rhn_filtered_products | first).id }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" mode: '0640' - owner: "{{ lookup('env', 'USER') | default(omit) }}" no_log: "{{ omit_rhn_output | default(true) }}" delegate_to: localhost run_once: true From a45b18dc85ecf57802d450de9b4be83dfdc84319 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 6 May 2024 13:02:51 +0200 Subject: [PATCH 252/376] kc.sh build uses configured jdk --- roles/keycloak_quarkus/tasks/rebuild_config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/roles/keycloak_quarkus/tasks/rebuild_config.yml b/roles/keycloak_quarkus/tasks/rebuild_config.yml index 5a715c6..5d2247d 100644 --- a/roles/keycloak_quarkus/tasks/rebuild_config.yml +++ b/roles/keycloak_quarkus/tasks/rebuild_config.yml @@ -3,5 +3,8 @@ - name: "Rebuild {{ keycloak.service_name }} config" ansible.builtin.shell: | {{ keycloak.home }}/bin/kc.sh build + environment: + PATH: "{{ keycloak_quarkus_java_home | default(keycloak_quarkus_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + JAVA_HOME: "{{ keycloak_quarkus_java_home | default(keycloak_quarkus_pkg_java_home, true) }}" become: true changed_when: true From b497e946cce42b49311d33fa458def1c63642e1f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 7 May 2024 09:47:12 +0200 Subject: [PATCH 253/376] Bump tp 2.2.3 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index ae08f9b..1e6fd20 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.2.2" +version: "2.2.3" readme: README.md authors: - Romain Pelisse From 1115ee409a706e2453d5c9b321630ba08208e8e7 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 7 May 2024 10:18:43 +0200 Subject: [PATCH 254/376] Linter warnings fix pass --- .ansible-lint | 2 +- changelogs/config.yaml | 32 +++++++++---------- roles/keycloak/meta/argument_specs.yml | 10 ++++-- roles/keycloak/tasks/fastpackages.yml | 7 ++-- roles/keycloak/tasks/install.yml | 24 +++++++------- roles/keycloak/tasks/jdbc_driver.yml | 11 ++++--- roles/keycloak/tasks/prereqs.yml | 9 ++++-- roles/keycloak/tasks/restart_keycloak.yml | 2 +- roles/keycloak/tasks/rhsso_cli.yml | 2 +- roles/keycloak/tasks/rhsso_patch.yml | 12 +++---- roles/keycloak/tasks/systemd.yml | 6 ++-- roles/keycloak/vars/debian.yml | 5 +-- roles/keycloak/vars/main.yml | 14 +++++--- roles/keycloak_quarkus/handlers/main.yml | 2 +- .../keycloak_quarkus/meta/argument_specs.yml | 8 +++-- roles/keycloak_quarkus/tasks/install.yml | 4 +-- roles/keycloak_quarkus/tasks/jdbc_driver.yml | 8 +++-- 17 files changed, 90 insertions(+), 68 deletions(-) diff --git a/.ansible-lint b/.ansible-lint index 92e5eaf..9c2702e 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -28,7 +28,6 @@ warn_list: - name[casing] - fqcn[action] - schema[meta] - - var-naming[no-role-prefix] - key-order[task] - blocked_modules @@ -36,6 +35,7 @@ skip_list: - vars_should_not_be_used - file_is_small_enough - name[template] + - var-naming[no-role-prefix] use_default_rules: true parseable: true diff --git a/changelogs/config.yaml b/changelogs/config.yaml index 374ae65..3c7fb7e 100644 --- a/changelogs/config.yaml +++ b/changelogs/config.yaml @@ -11,22 +11,22 @@ notesdir: fragments prelude_section_name: release_summary prelude_section_title: Release Summary sections: -- - major_changes - - Major Changes -- - minor_changes - - Minor Changes -- - breaking_changes - - Breaking Changes / Porting Guide -- - deprecated_features - - Deprecated Features -- - removed_features - - Removed Features -- - security_fixes - - Security Fixes -- - bugfixes - - Bugfixes -- - known_issues - - Known Issues + - - major_changes + - Major Changes + - - minor_changes + - Minor Changes + - - breaking_changes + - Breaking Changes / Porting Guide + - - deprecated_features + - Deprecated Features + - - removed_features + - Removed Features + - - security_fixes + - Security Fixes + - - bugfixes + - Bugfixes + - - known_issues + - Known Issues title: middleware_automation.keycloak trivial_section_name: trivial use_fqcn: true diff --git a/roles/keycloak/meta/argument_specs.yml b/roles/keycloak/meta/argument_specs.yml index eab89cf..5f6052d 100644 --- a/roles/keycloak/meta/argument_specs.yml +++ b/roles/keycloak/meta/argument_specs.yml @@ -86,7 +86,9 @@ argument_specs: type: "str" keycloak_features: default: "[]" - description: "List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]`" + description: > + List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, + example: `[ { name: 'docker', status: 'enabled' } ]` type: "list" keycloak_bind_address: default: "0.0.0.0" @@ -310,7 +312,8 @@ argument_specs: type: "str" keycloak_jgroups_subnet: required: false - description: "Override the subnet match for jgroups cluster formation; if not defined, it will be inferred from local machine route configuration" + description: > + Override the subnet match for jgroups cluster formation; if not defined, it will be inferred from local machine route configuration type: "str" keycloak_log_target: default: '/var/log/keycloak' @@ -323,7 +326,8 @@ argument_specs: description: "Set a username with which to authenticate when downloading JDBC drivers from an alternative location" type: "str" keycloak_jdbc_download_pass: - description: "Set a password with which to authenticate when downloading JDBC drivers from an alternative location (requires keycloak_jdbc_download_user)" + description: > + Set a password with which to authenticate when downloading JDBC drivers from an alternative location (requires keycloak_jdbc_download_user) type: "str" keycloak_jdbc_download_validate_certs: default: true diff --git a/roles/keycloak/tasks/fastpackages.yml b/roles/keycloak/tasks/fastpackages.yml index 3b557ef..be34c72 100644 --- a/roles/keycloak/tasks/fastpackages.yml +++ b/roles/keycloak/tasks/fastpackages.yml @@ -8,7 +8,8 @@ - name: "Add missing packages to the yum install list" ansible.builtin.set_fact: - packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" + packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | \ + map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" when: ansible_facts.os_family == "RedHat" - name: "Install packages: {{ packages_to_install }}" @@ -17,8 +18,8 @@ name: "{{ packages_to_install }}" state: present when: - - packages_to_install | default([]) | length > 0 - - ansible_facts.os_family == "RedHat" + - packages_to_install | default([]) | length > 0 + - ansible_facts.os_family == "RedHat" - name: "Install packages: {{ packages_list }}" become: true diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml index 67b98cd..b620b03 100644 --- a/roles/keycloak/tasks/install.yml +++ b/roles/keycloak/tasks/install.yml @@ -41,8 +41,8 @@ ansible.builtin.user: name: "{{ keycloak_service_user }}" home: /opt/keycloak - system: yes - create_home: no + system: true + create_home: false - name: "Create install location for {{ keycloak.service_name }}" become: true @@ -51,7 +51,7 @@ state: directory owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" - mode: 0750 + mode: '0750' - name: Create pidfile folder become: true @@ -60,7 +60,7 @@ state: directory owner: "{{ keycloak_service_user if keycloak_service_runas else omit }}" group: "{{ keycloak_service_group if keycloak_service_runas else omit }}" - mode: 0750 + mode: '0750' ## check remote archive - name: Set download archive path @@ -84,7 +84,7 @@ ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user url: "{{ keycloak_download_url }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" - mode: 0644 + mode: '0644' delegate_to: localhost run_once: true when: @@ -136,7 +136,7 @@ ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user url: "{{ keycloak_rhsso_download_url }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" - mode: 0644 + mode: '0644' delegate_to: localhost run_once: true when: @@ -160,7 +160,7 @@ dest: "{{ archive }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" - mode: 0640 + mode: '0640' register: new_version_downloaded when: - not archive_path.stat.exists @@ -221,7 +221,7 @@ dest: "{{ keycloak_config_path_to_standalone_xml }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" - mode: 0640 + mode: '0640' notify: - restart keycloak when: keycloak_config_override_template | length > 0 @@ -233,7 +233,7 @@ dest: "{{ keycloak_config_path_to_standalone_xml }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" - mode: 0640 + mode: '0640' notify: - restart keycloak when: @@ -261,7 +261,7 @@ dest: "{{ keycloak_config_path_to_standalone_xml }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" - mode: 0640 + mode: '0640' notify: - restart keycloak when: @@ -276,7 +276,7 @@ dest: "{{ keycloak_config_path_to_standalone_xml }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" - mode: 0640 + mode: '0640' notify: - restart keycloak when: @@ -291,7 +291,7 @@ dest: "{{ keycloak_config_path_to_properties }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" - mode: 0640 + mode: '0640' notify: - restart keycloak when: keycloak_features | length > 0 diff --git a/roles/keycloak/tasks/jdbc_driver.yml b/roles/keycloak/tasks/jdbc_driver.yml index a7cd8ab..bec80e3 100644 --- a/roles/keycloak/tasks/jdbc_driver.yml +++ b/roles/keycloak/tasks/jdbc_driver.yml @@ -12,7 +12,7 @@ recurse: true owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" - mode: 0750 + mode: '0750' become: true when: - not dest_path.stat.exists @@ -20,8 +20,9 @@ ansible.builtin.fail: msg: >- When JDBC driver download credentials are set, both the username and the password MUST be set - when: - - (keycloak_jdbc_download_user is undefined and keycloak_jdbc_download_pass is not undefined) or (keycloak_jdbc_download_pass is undefined and keycloak_jdbc_download_user is not undefined) + when: > + (keycloak_jdbc_download_user is undefined and keycloak_jdbc_download_pass is not undefined) or + (keycloak_jdbc_download_pass is undefined and keycloak_jdbc_download_user is not undefined) - name: "Retrieve JDBC Driver from {{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_url }}" ansible.builtin.get_url: @@ -32,7 +33,7 @@ url_username: "{{ keycloak_jdbc_download_user | default(omit) }}" url_password: "{{ keycloak_jdbc_download_pass | default(omit) }}" validate_certs: "{{ keycloak_jdbc_download_validate_certs | default(omit) }}" - mode: 0640 + mode: '0640' become: true - name: "Deploy module.xml for JDBC Driver" @@ -41,5 +42,5 @@ dest: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}/module.xml" group: "{{ keycloak_service_group }}" owner: "{{ keycloak_service_user }}" - mode: 0640 + mode: '0640' become: true diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml index c92bb1c..d97390c 100644 --- a/roles/keycloak/tasks/prereqs.yml +++ b/roles/keycloak/tasks/prereqs.yml @@ -4,13 +4,16 @@ that: - keycloak_admin_password | length > 12 quiet: true - fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_admin_password variable to a 12+ char long string" + fail_msg: > + The console administrator password is empty or invalid. Please set the keycloak_admin_password variable to a 12+ char long string success_msg: "{{ 'Console administrator password OK' }}" - name: Validate configuration ansible.builtin.assert: - that: - - (keycloak_ha_enabled and keycloak_db_enabled) or (not keycloak_ha_enabled and keycloak_db_enabled) or (not keycloak_ha_enabled and not keycloak_db_enabled) + that: > + (keycloak_ha_enabled and keycloak_db_enabled) or + (not keycloak_ha_enabled and keycloak_db_enabled) or + (not keycloak_ha_enabled and not keycloak_db_enabled) quiet: true fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_ha_enabled and keycloak_db_enabled" success_msg: "{{ 'Configuring HA' if keycloak_ha_enabled else 'Configuring standalone' }}" diff --git a/roles/keycloak/tasks/restart_keycloak.yml b/roles/keycloak/tasks/restart_keycloak.yml index bae91cd..7284bd0 100644 --- a/roles/keycloak/tasks/restart_keycloak.yml +++ b/roles/keycloak/tasks/restart_keycloak.yml @@ -22,7 +22,7 @@ - name: "Restart and enable {{ keycloak.service_name }} service" ansible.builtin.systemd: name: keycloak - enabled: yes + enabled: true state: restarted become: true when: inventory_hostname != ansible_play_hosts | first diff --git a/roles/keycloak/tasks/rhsso_cli.yml b/roles/keycloak/tasks/rhsso_cli.yml index c51cdc7..fd41dd6 100644 --- a/roles/keycloak/tasks/rhsso_cli.yml +++ b/roles/keycloak/tasks/rhsso_cli.yml @@ -10,4 +10,4 @@ ansible.builtin.command: > {{ keycloak.cli_path }} --connect --command='{{ query }}' --controller={{ keycloak_host }}:{{ keycloak_management_http_port }} changed_when: false - register: cli_result \ No newline at end of file + register: cli_result diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index 191a3e0..e7ac3f0 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -45,7 +45,7 @@ - name: Determine latest version ansible.builtin.set_fact: - sso_latest_version: "{{ filtered_versions | middleware_automation.common.version_sort | last }}" + sso_latest_version: "{{ filtered_versions | middleware_automation.common.version_sort | last }}" when: sso_patch_version is not defined or sso_patch_version | length == 0 delegate_to: localhost run_once: true @@ -95,7 +95,7 @@ dest: "{{ patch_archive }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" - mode: 0640 + mode: '0640' register: new_version_downloaded when: - not patch_archive_path.stat.exists @@ -135,8 +135,8 @@ - cli_result.rc == 0 args: apply: - become: true - become_user: "{{ keycloak_service_user }}" + become: true + become_user: "{{ keycloak_service_user }}" - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" ansible.builtin.uri: @@ -152,8 +152,8 @@ query: "patch info" args: apply: - become: true - become_user: "{{ keycloak_service_user }}" + become: true + become_user: "{{ keycloak_service_user }}" - name: "Verify installed patch version" ansible.builtin.assert: diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml index 797eb7b..1653406 100644 --- a/roles/keycloak/tasks/systemd.yml +++ b/roles/keycloak/tasks/systemd.yml @@ -6,7 +6,7 @@ dest: "{{ keycloak_dest }}/keycloak-service.sh" owner: root group: root - mode: 0755 + mode: '0755' notify: - restart keycloak @@ -17,7 +17,7 @@ dest: "{{ keycloak_sysconf_file }}" owner: root group: root - mode: 0644 + mode: '0644' notify: - restart keycloak @@ -27,7 +27,7 @@ dest: /etc/systemd/system/keycloak.service owner: root group: root - mode: 0644 + mode: '0644' become: true register: systemdunit notify: diff --git a/roles/keycloak/vars/debian.yml b/roles/keycloak/vars/debian.yml index 60cdfa8..b005b0a 100644 --- a/roles/keycloak/vars/debian.yml +++ b/roles/keycloak/vars/debian.yml @@ -6,6 +6,7 @@ keycloak_prereq_package_list: - procps - apt - tzdata -keycloak_configure_iptables: True +keycloak_configure_iptables: true keycloak_sysconf_file: /etc/default/keycloak -keycloak_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_varjvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" +keycloak_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_varjvm_package | \ + regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index b03a1a5..7f7dfd1 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -13,7 +13,8 @@ keycloak: service_name: "{{ keycloak_service_name }}" health_url: "{{ keycloak_management_url }}/health" cli_path: "{{ keycloak_jboss_home }}/bin/jboss-cli.sh" - config_template_source: "{{ keycloak_config_override_template if keycloak_config_override_template | length > 0 else 'standalone-ha.xml.j2' if keycloak_remote_cache_enabled else 'standalone.xml.j2' }}" + config_template_source: "{{ keycloak_config_override_template if keycloak_config_override_template | length > 0 \ + else 'standalone-ha.xml.j2' if keycloak_remote_cache_enabled else 'standalone.xml.j2' }}" features: "{{ keycloak_features }}" # database @@ -26,7 +27,8 @@ keycloak_jdbc: driver_module_dir: "{{ keycloak_jboss_home }}/modules/org/postgresql/main" driver_version: "{{ keycloak_jdbc_driver_version }}" driver_jar_filename: "postgresql-{{ keycloak_jdbc_driver_version }}.jar" - driver_jar_url: "https://repo.maven.apache.org/maven2/org/postgresql/postgresql/{{ keycloak_jdbc_driver_version }}/postgresql-{{ keycloak_jdbc_driver_version }}.jar" + driver_jar_url: > + {{ keycloak_maven_central }}org/postgresql/postgresql/{{ keycloak_jdbc_driver_version }}/postgresql-{{ keycloak_jdbc_driver_version }}.jar connection_url: "{{ keycloak_jdbc_url }}" db_user: "{{ keycloak_db_user }}" db_password: "{{ keycloak_db_pass }}" @@ -46,7 +48,8 @@ keycloak_jdbc: driver_module_dir: "{{ keycloak_jboss_home }}/modules/org/mariadb/main" driver_version: "{{ keycloak_jdbc_driver_version }}" driver_jar_filename: "mariadb-java-client-{{ keycloak_jdbc_driver_version }}.jar" - driver_jar_url: "https://repo1.maven.org/maven2/org/mariadb/jdbc/mariadb-java-client/{{ keycloak_jdbc_driver_version }}/mariadb-java-client-{{ keycloak_jdbc_driver_version }}.jar" + driver_jar_url: > + {{ keycloak_maven_central }}org/mariadb/jdbc/mariadb-java-client/{{ keycloak_jdbc_driver_version }}/mariadb-java-client-{{ keycloak_jdbc_driver_version }}.jar connection_url: "{{ keycloak_jdbc_url }}" db_user: "{{ keycloak_db_user }}" db_password: "{{ keycloak_db_pass }}" @@ -67,7 +70,8 @@ keycloak_jdbc: driver_module_dir: "{{ keycloak_jboss_home }}/modules/com/microsoft/sqlserver/main" driver_version: "{{ keycloak_jdbc_driver_version }}" driver_jar_filename: "mssql-java-client-{{ keycloak_jdbc_driver_version }}.jar" - driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/{{ keycloak_jdbc_driver_version }}.jre11/mssql-jdbc-{{ keycloak_jdbc_driver_version }}.jre11.jar" # e.g., https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar + driver_jar_url: > + {{ keycloak_maven_central }}com/microsoft/sqlserver/mssql-jdbc/{{ keycloak_jdbc_driver_version }}.jre11/mssql-jdbc-{{ keycloak_jdbc_driver_version }}.jre11.jar connection_url: "{{ keycloak_jdbc_url }}" db_user: "{{ keycloak_db_user }}" db_password: "{{ keycloak_db_pass }}" @@ -102,3 +106,5 @@ keycloak_remotecache: use_ssl: "{{ keycloak_infinispan_use_ssl }}" trust_store_path: "{{ keycloak_infinispan_trust_store_path }}" trust_store_password: "{{ keycloak_infinispan_trust_store_password }}" + +keycloak_maven_central: https://repo1.maven.org/maven2/ diff --git a/roles/keycloak_quarkus/handlers/main.yml b/roles/keycloak_quarkus/handlers/main.yml index f60e747..b95d5c3 100644 --- a/roles/keycloak_quarkus/handlers/main.yml +++ b/roles/keycloak_quarkus/handlers/main.yml @@ -12,6 +12,6 @@ - name: "Print deprecation warning" ansible.builtin.fail: msg: "Deprecation warning: you are using the deprecated variable '{{ deprecated_variable | d('NotSet') }}', check docs on how to upgrade." - ignore_errors: true failed_when: false + changed_when: true listen: "print deprecation warning" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 5fccedc..a8b1a05 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -170,7 +170,9 @@ argument_specs: type: "str" keycloak_quarkus_config_key_store_password: default: "" - description: "Password of the configuration key store; if non-empty, `keycloak_quarkus_db_pass` will be saved to the key store at `keycloak_quarkus_config_key_store_file` (instead of being written to the configuration file in clear text" + description: > + Password of the configuration key store; if non-empty, `keycloak_quarkus_db_pass` will be saved to the key store + at `keycloak_quarkus_config_key_store_file` (instead of being written to the configuration file in clear text) type: "str" keycloak_quarkus_https_port: default: 8443 @@ -399,7 +401,9 @@ argument_specs: description: "Set a username with which to authenticate when downloading JDBC drivers from an alternative location" type: "str" keycloak_quarkus_jdbc_download_pass: - description: "Set a password with which to authenticate when downloading JDBC drivers from an alternative location (requires keycloak_quarkus_jdbc_download_user)" + description: > + Set a password with which to authenticate when downloading JDBC drivers from an alternative location + (requires `keycloak_quarkus_jdbc_download_user``) type: "str" keycloak_quarkus_jdbc_download_validate_certs: default: true diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 732e5b1..65fd391 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -170,7 +170,7 @@ dest: "{{ keycloak_quarkus_key_file }}" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0640 + mode: '0640' become: true when: - keycloak_quarkus_https_key_file_enabled is defined and keycloak_quarkus_https_key_file_enabled @@ -183,7 +183,7 @@ dest: "{{ keycloak_quarkus_cert_file }}" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" - mode: 0644 + mode: '0644' become: true when: - keycloak_quarkus_https_key_file_enabled is defined and keycloak_quarkus_https_key_file_enabled diff --git a/roles/keycloak_quarkus/tasks/jdbc_driver.yml b/roles/keycloak_quarkus/tasks/jdbc_driver.yml index 52298aa..880a915 100644 --- a/roles/keycloak_quarkus/tasks/jdbc_driver.yml +++ b/roles/keycloak_quarkus/tasks/jdbc_driver.yml @@ -3,9 +3,11 @@ ansible.builtin.fail: msg: >- When JDBC driver download credentials are set, both the username and the password MUST be set - when: - - (keycloak_quarkus_jdbc_download_user is undefined and keycloak_quarkus_jdbc_download_pass is not undefined) or (keycloak_quarkus_jdbc_download_pass is undefined and keycloak_quarkus_jdbc_download_user is not undefined) -- name: "Retrieve JDBC Driver from {{ keycloak_jdbc_download_user | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" + when: > + (keycloak_quarkus_jdbc_download_user is undefined and keycloak_quarkus_jdbc_download_pass is not undefined) or + (keycloak_quarkus_jdbc_download_pass is undefined and keycloak_quarkus_jdbc_download_user is not undefined) + +- name: "Retrieve JDBC Driver from {{ keycloak_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" ansible.builtin.get_url: url: "{{ keycloak_quarkus_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" dest: "{{ keycloak.home }}/providers" From a0198238715563bfd0fe13e1b72c7fc6659a5424 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 8 May 2024 17:15:50 +0200 Subject: [PATCH 255/376] Close #214: RHBK 24.*: Update sqlserver JDBC version --- roles/keycloak_quarkus/defaults/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index a54e6c7..5a11f08 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -130,9 +130,9 @@ keycloak_quarkus_default_jdbc: version: 2.7.4 mssql: url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;' - version: 12.2.0 - driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar" - # cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/22.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver + version: 12.4.2 + driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.4.2.jre11/mssql-jdbc-12.4.2.jre11.jar" + # cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/24.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver ### logging configuration keycloak_quarkus_log: file keycloak_quarkus_log_level: info From 3c224176743f71af3d50377d97ca3889f7f7ddf7 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 8 May 2024 19:03:30 +0200 Subject: [PATCH 256/376] Port downstream upgrade --- molecule/quarkus_upgrade/converge.yml | 9 +++++ molecule/quarkus_upgrade/molecule.yml | 43 ++++++++++++++++++++++ molecule/quarkus_upgrade/prepare.yml | 52 +++++++++++++++++++++++++++ molecule/quarkus_upgrade/vars.yml | 14 ++++++++ molecule/quarkus_upgrade/verify.yml | 32 +++++++++++++++++ 5 files changed, 150 insertions(+) create mode 100644 molecule/quarkus_upgrade/converge.yml create mode 100644 molecule/quarkus_upgrade/molecule.yml create mode 100644 molecule/quarkus_upgrade/prepare.yml create mode 100644 molecule/quarkus_upgrade/vars.yml create mode 100644 molecule/quarkus_upgrade/verify.yml diff --git a/molecule/quarkus_upgrade/converge.yml b/molecule/quarkus_upgrade/converge.yml new file mode 100644 index 0000000..eb84589 --- /dev/null +++ b/molecule/quarkus_upgrade/converge.yml @@ -0,0 +1,9 @@ +--- +- name: Converge + hosts: all + vars_files: + - vars.yml + vars: + keycloak_quarkus_version: 24.0.3 + roles: + - role: keycloak_quarkus diff --git a/molecule/quarkus_upgrade/molecule.yml b/molecule/quarkus_upgrade/molecule.yml new file mode 100644 index 0000000..77f687f --- /dev/null +++ b/molecule/quarkus_upgrade/molecule.yml @@ -0,0 +1,43 @@ +--- +dependency: + name: galaxy + options: + requirements-file: molecule/requirements.yml +driver: + name: docker +platforms: + - name: instance + image: registry.access.redhat.com/ubi9/ubi-init:latest + command: "/usr/sbin/init" + pre_build_image: true + privileged: true + port_bindings: + - 8080:8080 + published_ports: + - 0.0.0.0:8080:8080/TCP +provisioner: + name: ansible + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: "{{ ansible_playbook_python }}" +verifier: + name: ansible +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/quarkus_upgrade/prepare.yml b/molecule/quarkus_upgrade/prepare.yml new file mode 100644 index 0000000..1a0e708 --- /dev/null +++ b/molecule/quarkus_upgrade/prepare.yml @@ -0,0 +1,52 @@ +--- +- name: Prepare + hosts: all + vars_files: + - vars.yml + vars: + sudo_pkg_name: sudo + keycloak_quarkus_version: 22.0.10 + pre_tasks: + - name: Install sudo + ansible.builtin.apt: + name: + - sudo + - openjdk-17-jdk-headless + state: present + when: + - ansible_facts.os_family == 'Debian' + + - name: "Ensure common prepare phase are set." + ansible.builtin.include_tasks: ../prepare.yml + + - name: Display Ansible version + ansible.builtin.debug: + msg: "Ansible version is {{ ansible_version.full }}" + + - name: "Ensure {{ sudo_pkg_name }} is installed (if user is root)." + ansible.builtin.dnf: + name: "{{ sudo_pkg_name }}" + when: + - ansible_user_id == 'root' + + - name: Gather the package facts + ansible.builtin.package_facts: + manager: auto + + - name: "Check if {{ sudo_pkg_name }} is installed." + ansible.builtin.assert: + that: + - sudo_pkg_name in ansible_facts.packages + + - name: Create certificate request + ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' + delegate_to: localhost + changed_when: false + roles: + - role: keycloak_quarkus + post_tasks: + - name: "Delete custom fact" + ansible.builtin.file: + path: /etc/ansible/facts.d/keycloak.fact + state: absent + become: true diff --git a/molecule/quarkus_upgrade/vars.yml b/molecule/quarkus_upgrade/vars.yml new file mode 100644 index 0000000..81d56b5 --- /dev/null +++ b/molecule/quarkus_upgrade/vars.yml @@ -0,0 +1,14 @@ +--- +keycloak_quarkus_offline_install: false +keycloak_quarkus_admin_password: "remembertochangeme" +keycloak_quarkus_admin_pass: "remembertochangeme" +keycloak_quarkus_realm: TestRealm +keycloak_quarkus_host: instance +keycloak_quarkus_log: file +keycloak_quarkus_https_key_file_enabled: true +keycloak_quarkus_log_target: /tmp/keycloak +keycloak_quarkus_hostname_strict: false +keycloak_quarkus_cert_file_copy_enabled: true +keycloak_quarkus_key_file_copy_enabled: true +keycloak_quarkus_key_content: "{{ lookup('file', 'key.pem') }}" +keycloak_quarkus_cert_file_src: cert.pem diff --git a/molecule/quarkus_upgrade/verify.yml b/molecule/quarkus_upgrade/verify.yml new file mode 100644 index 0000000..def2d5d --- /dev/null +++ b/molecule/quarkus_upgrade/verify.yml @@ -0,0 +1,32 @@ +--- +- name: Verify + hosts: instance + vars: + keycloak_quarkus_admin_password: "remembertochangeme" + keycloak_quarkus_port: http://localhost:8080 + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + + - name: Check if keycloak service started + ansible.builtin.assert: + that: + - ansible_facts.services["rhbk.service"]["state"] == "running" + - ansible_facts.services["rhbk.service"]["status"] == "enabled" + + - name: Verify we are running on requested jvm + ansible.builtin.shell: | + set -eo pipefail + ps -ef | grep 'etc/alternatives/.*17' | grep -v grep + changed_when: false + + - name: Verify token api call + ansible.builtin.uri: + url: "{{ keycloak_quarkus_port }}/realms/master/protocol/openid-connect/token" + method: POST + body: "client_id=admin-cli&username=admin&password={{ keycloak_quarkus_admin_password }}&grant_type=password" + validate_certs: no + register: keycloak_auth_response + until: keycloak_auth_response.status == 200 + retries: 2 + delay: 2 From 22f5ad902f1372b701ab81c43cccf6a48eb6080c Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 8 May 2024 19:05:24 +0200 Subject: [PATCH 257/376] add test to github actions --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 509bebb..d5cac41 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode", "debian" ] + [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode", "quarkus_upgrade", "debian" ] From 4c96cbe7f6d1aca3279f54179dd0c11b2b450e4c Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 8 May 2024 19:09:59 +0200 Subject: [PATCH 258/376] use sane version to be upgraded --- molecule/quarkus_upgrade/prepare.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/molecule/quarkus_upgrade/prepare.yml b/molecule/quarkus_upgrade/prepare.yml index 1a0e708..bebfc68 100644 --- a/molecule/quarkus_upgrade/prepare.yml +++ b/molecule/quarkus_upgrade/prepare.yml @@ -5,7 +5,7 @@ - vars.yml vars: sudo_pkg_name: sudo - keycloak_quarkus_version: 22.0.10 + keycloak_quarkus_version: 23.0.7 pre_tasks: - name: Install sudo ansible.builtin.apt: From 4bbc8e02566732f4550ff8718d753d8152ffd644 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 8 May 2024 19:14:04 +0200 Subject: [PATCH 259/376] update systemd service name in verify --- molecule/quarkus_upgrade/verify.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/molecule/quarkus_upgrade/verify.yml b/molecule/quarkus_upgrade/verify.yml index def2d5d..f5edfd0 100644 --- a/molecule/quarkus_upgrade/verify.yml +++ b/molecule/quarkus_upgrade/verify.yml @@ -11,8 +11,8 @@ - name: Check if keycloak service started ansible.builtin.assert: that: - - ansible_facts.services["rhbk.service"]["state"] == "running" - - ansible_facts.services["rhbk.service"]["status"] == "enabled" + - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" - name: Verify we are running on requested jvm ansible.builtin.shell: | From fcf629d05e22eedffb279f645382347ae3ef3a06 Mon Sep 17 00:00:00 2001 From: Footur <3769085+Footur@users.noreply.github.com> Date: Thu, 9 May 2024 07:24:47 +0000 Subject: [PATCH 260/376] Update Keycloak to version 24.0.4 --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index ccb9e75..a70deae 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -11,7 +11,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `24.0.3` | +|`keycloak_quarkus_version`| keycloak.org package version | `24.0.4` | |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 5a11f08..242482d 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 24.0.3 +keycloak_quarkus_version: 24.0.4 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index a8b1a05..56a99ce 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -2,7 +2,7 @@ argument_specs: main: options: keycloak_quarkus_version: - default: "24.0.3" + default: "24.0.4" description: "keycloak.org package version" type: "str" keycloak_quarkus_archive: @@ -412,7 +412,7 @@ argument_specs: downstream: options: rhbk_version: - default: "24.0.3" + default: "24.0.4" description: "Red Hat Build of Keycloak version" type: "str" rhbk_archive: From 8f14be37d7ad512ea393a81ecca6db819eb79d20 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 10 May 2024 10:17:37 +0200 Subject: [PATCH 261/376] add functionality --- roles/keycloak_quarkus/README.md | 10 ++++++++++ roles/keycloak_quarkus/tasks/install.yml | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index a70deae..f7f1be3 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -185,6 +185,16 @@ Role Variables |`keycloak_quarkus_frontend_url`| Base URL for frontend URLs, including scheme, host, port and path | `no` | |`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` | |`keycloak_quarkus_ks_vault_pass`| The password for accessing the keystore vault SPI | `no` | +|`keycloak_quarkus_alternate_download_url`| Alternate location with optional authentication for downloading RHBK | `no` | +|`keycloak_quarkus_download_user`| Optional username for http authentication | `no*` | +|`keycloak_quarkus_download_pass`| Optional password for http authentication | `no*` | +|`keycloak_quarkus_download_validate_certs`| Whether to validate certs for URL `keycloak_quarkus_alternate_download_url` | `no` | +|`keycloak_quarkus_jdbc_download_user`| Optional username for http authentication | `no*` | +|`keycloak_quarkus_jdbc_download_pass`| Optional password for http authentication | `no*` | +|`keycloak_quarkus_jdbc_download_validate_certs`| Whether to validate certs for URL `keycloak_quarkus_download_validate_certs` | `no` | + +`*` username/password authentication credentials must be both declared or both undefined + Role custom facts ----------------- diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 65fd391..480ccbc 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -115,6 +115,25 @@ run_once: true become: false +- name: Perform download of RHBK from alternate download location + delegate_to: localhost + run_once: true + become: false + when: + - archive_path is defined + - archive_path.stat is defined + - not archive_path.stat.exists + - rhbk_enable is defined and rhbk_enable + - not keycloak.offline_install + - keycloak_quarkus_alternate_download_url is defined + ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user + url: "{{ keycloak_quarkus_alternate_download_url }}" + dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" + mode: '0640' + url_username: "{{ keycloak_quarkus_download_user | default(omit) }}" + url_password: "{{ keycloak_quarkus_download_pass | default(omit) }}" + validate_certs: "{{ keycloak_quarkus_download_validate_certs | default(omit) }}" + - name: Check downloaded archive ansible.builtin.stat: path: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" From 9f4623b05a776ec555e3a1581798a530fddf4cbd Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 14 May 2024 08:36:55 +0200 Subject: [PATCH 262/376] #224: keycloak_quarkus: Add support for policy files --- molecule/quarkus/converge.yml | 6 ++++++ roles/keycloak_quarkus/README.md | 16 ++++++++++++++++ roles/keycloak_quarkus/defaults/main.yml | 2 ++ roles/keycloak_quarkus/tasks/install.yml | 22 ++++++++++++++++++++++ roles/keycloak_quarkus/tasks/prereqs.yml | 10 ++++++++++ 5 files changed, 56 insertions(+) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 9e74aa6..2982250 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -31,6 +31,12 @@ value: 10 - id: spid-saml url: https://github.com/italia/spid-keycloak-provider/releases/download/24.0.2/spid-provider.jar + keycloak_quarkus_policies: + - name: "xato-net-10-million-passwords.txt" + url: "https://github.com/danielmiessler/SecLists/raw/master/Passwords/xato-net-10-million-passwords.txt" + - name: "xato-net-10-million-passwords-10.txt" + url: "https://github.com/danielmiessler/SecLists/raw/master/Passwords/xato-net-10-million-passwords-10.txt" + type: password-blacklists roles: - role: keycloak_quarkus - role: keycloak_realm diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index f7f1be3..47d5a21 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -176,6 +176,22 @@ bin/kc.sh build --spi-connections-provider=http-client --spi-connections-http-cl ``` +#### Configuring policies + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_policies`| List of policy definitions; see below | `[]` | + +Provider definition: + +```yaml +keycloak_quarkus_policies: + - name: xato-net-10-million-passwords.txt # required, resulting file name + url: https://github.com/danielmiessler/SecLists/raw/master/Passwords/xato-net-10-million-passwords.txt # required, url for download + type: password-blacklists # optional, defaults to `password-blacklists`; supported values: [`password-blacklists`] +``` + + Role Variables -------------- diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 242482d..8a4f9f1 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -150,3 +150,5 @@ keycloak_quarkus_ks_vault_type: PKCS12 keycloak_quarkus_ks_vault_pass: keycloak_quarkus_providers: [] +keycloak_quarkus_policies: [] +keycloak_quarkus_supported_policy_types: ['password-blacklists'] diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 480ccbc..ab7c396 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -226,3 +226,25 @@ loop: "{{ keycloak_quarkus_providers }}" when: item.url is defined and item.url | length > 0 notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or not item.restart else [] }}" + +- name: Ensure required folder structure for policies exits + ansible.builtin.file: + path: "{{ keycloak.home }}/data/{{ item | lower }}" + state: directory + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: '0750' + become: true + loop: "{{ keycloak_quarkus_supported_policy_types }}" + +- name: "Install custom policies" + ansible.builtin.get_url: + url: "{{ item.url }}" + dest: "{{ keycloak.home }}/data/{{ item.type|default(keycloak_quarkus_supported_policy_types | first) | lower }}/{{ item.name }}" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: '0640' + become: true + loop: "{{ keycloak_quarkus_policies }}" + when: item.url is defined and item.url | length > 0 + notify: "restart keycloak" diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index e0a76d5..1e422a7 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -65,3 +65,13 @@ quiet: true fail_msg: "Providers definition is incorrect; `id` and one of `spi` or `url` are mandatory. `key` and `value` are mandatory for each property" loop: "{{ keycloak_quarkus_providers }}" + +- name: "Validate policies" + ansible.builtin.assert: + that: + - item.name is defined and item.name | length > 0 + - item.url is defined and item.url | length > 0 + - item.type is not defined or item.type | lower in keycloak_quarkus_supported_policy_types + quiet: true + fail_msg: "Policy definition is incorrect: `name` and one of `url` are mandatory, `type` needs to be left empty or one of {{ keycloak_quarkus_supported_policy_types }}." + loop: "{{ keycloak_quarkus_policies }}" From 6682853a2d105aa701ac9f30a33b47ebf1e0f028 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 14 May 2024 08:58:57 +0200 Subject: [PATCH 263/376] #224: Add missing argument specs --- roles/keycloak_quarkus/meta/argument_specs.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 56a99ce..c5f5138 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -394,6 +394,14 @@ argument_specs: description: "List of provider definition dicts: { 'id': str, 'spi': str, 'url': str, 'default': bool, 'properties': list of key/value }" default: [] type: "list" + keycloak_quarkus_supported_policy_types: + description: "List of str of supported policy types" + default: ['password-blacklists'] + type: "list" + keycloak_quarkus_policies: + description: "List of policy definition dicts: { 'name': str, 'url': str, 'type': str }" + default: [] + type: "list" keycloak_quarkus_jdbc_download_url: description: "Override the default Maven Central download URL for the JDBC driver" type: "str" From 4b902adc8d4598dc1ce3ca98f3f0ae3670aaa435 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 13 May 2024 17:20:21 +0200 Subject: [PATCH 264/376] #222: Add support for maven providers --- requirements.txt | 5 ++-- requirements.yml | 1 + roles/keycloak_quarkus/README.md | 34 ++++++++++++++++++++++-- roles/keycloak_quarkus/tasks/install.yml | 33 +++++++++++++++++++++-- roles/keycloak_quarkus/tasks/prereqs.yml | 4 +-- 5 files changed, 69 insertions(+), 8 deletions(-) diff --git a/requirements.txt b/requirements.txt index b2366a5..a91d12a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ ################################################# -# python dependencies required to be installed +# python dependencies required to be installed # on the controller host with: # pip install -r requirements.txt # -netaddr \ No newline at end of file +netaddr +lxml # for community.general.maven_artifact \ No newline at end of file diff --git a/requirements.yml b/requirements.yml index 3f6feef..10150ad 100644 --- a/requirements.yml +++ b/requirements.yml @@ -2,3 +2,4 @@ collections: - name: middleware_automation.common - name: ansible.posix + - name: community.general # for `maven_artifact` diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 47d5a21..028097c 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -4,6 +4,29 @@ keycloak_quarkus Install [keycloak](https://keycloak.org/) >= 20.0.0 (quarkus) server configurations. +Requirements +------------ + +This role requires the `python3-netaddr` and `lxml` library installed on the controller node. + +* to install via yum/dnf: `dnf install python3-netaddr python3-lxml` +* to install via apt: `apt install python3-netaddr python3-lxml` +* or via the collection: `pip install -r requirements.txt` + + +Dependencies +------------ + +The roles depends on: + +* [middleware_automation.common](https://github.com/ansible-middleware/common) +* [ansible-posix](https://docs.ansible.com/ansible/latest/collections/ansible/posix/index.html) +* [community.general](https://docs.ansible.com/ansible/latest/collections/community/general/index.html) + +To install all the dependencies via galaxy: + + ansible-galaxy collection install -r requirements.yml + Role Defaults ------------- @@ -160,10 +183,17 @@ Provider definition: ```yaml keycloak_quarkus_providers: - id: http-client # required - spi: connections # required if url is not specified + spi: connections # required if neither url nor maven are specified default: true # optional, whether to set default for spi, default false restart: true # optional, whether to restart, default true - url: https://.../.../custom_spi.jar # optional, url for download + url: https://.../.../custom_spi.jar # optional, url for download via http + maven: # optional, for download using maven + repository_url: https://maven.pkg.github.com/OWNER/REPOSITORY # optional, maven repo url + group_id: my.group # optional, maven group id + artifact_id: artifact # optional, maven artifact id + version: 24.0.4 # optional, defaults to latest + username: user # optional, cf. https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry#authenticating-to-github-packages + password: pat # optional, provide a PAT for accessing Github's Apache Maven registry properties: # optional, list of key-values - key: default-connection-pool-size value: 10 diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index ab7c396..8d604e6 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -215,7 +215,7 @@ - rhbk_enable is defined and rhbk_enable - keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url is defined -- name: "Download custom providers" +- name: "Download custom providers via http" ansible.builtin.get_url: url: "{{ item.url }}" dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar" @@ -227,7 +227,36 @@ when: item.url is defined and item.url | length > 0 notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or not item.restart else [] }}" -- name: Ensure required folder structure for policies exits +# this requires the `lxml` package to be installed; we redirect this step to localhost such that we do need to install it on the remote hosts +- name: "Download custom providers to localhost using maven" + community.general.maven_artifact: + repository_url: "{{ item.maven.repository_url }}" + group_id: "{{ item.maven.group_id }}" + artifact_id: "{{ item.maven.artifact_id }}" + version: "{{ item.maven.version | default(omit) }}" + username: "{{ item.maven.username | default(omit) }}" + password: "{{ item.maven.password | default(omit) }}" + dest: "{{ local_path.stat.path }}/{{ item.id }}.jar" + delegate_to: "localhost" + run_once: true + loop: "{{ keycloak_quarkus_providers }}" + when: item.maven is defined + no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" + notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or not item.restart else [] }}" + +- name: "Upload local maven SPIs" + ansible.builtin.copy: + src: "{{ local_path.stat.path }}/{{ item.id }}.jar" + dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: '0640' + become: true + loop: "{{ keycloak_quarkus_providers }}" + when: item.maven is defined + no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" + +- name: Ensure required folder structure for policies exists ansible.builtin.file: path: "{{ keycloak.home }}/data/{{ item | lower }}" state: directory diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 1e422a7..064cc10 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -61,9 +61,9 @@ ansible.builtin.assert: that: - item.id is defined and item.id | length > 0 - - (item.spi is defined and item.spi | length > 0) or (item.url is defined and item.url | length > 0) + - (item.spi is defined and item.spi | length > 0) or (item.url is defined and item.url | length > 0) or (item.maven is defined and item.maven.repository_url is defined and item.maven.repository_url | length > 0 and item.maven.group_id is defined and item.maven.group_id | length > 0 and item.maven.artifact_id is defined and item.maven.artifact_id | length > 0) quiet: true - fail_msg: "Providers definition is incorrect; `id` and one of `spi` or `url` are mandatory. `key` and `value` are mandatory for each property" + fail_msg: "Providers definition is incorrect; `id` and one of `spi`, `url`, or `maven` are mandatory. `key` and `value` are mandatory for each property" loop: "{{ keycloak_quarkus_providers }}" - name: "Validate policies" From d8e9620a8a26381eb272c3125c9b5adb0183fcc0 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 13 May 2024 17:20:32 +0200 Subject: [PATCH 265/376] #222: Molecule tests --- molecule/quarkus/converge.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 2982250..6186af4 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -31,6 +31,14 @@ value: 10 - id: spid-saml url: https://github.com/italia/spid-keycloak-provider/releases/download/24.0.2/spid-provider.jar + - id: keycloak-kerberos-federation + maven: + repository_url: https://repo1.maven.org/maven2/ # https://mvnrepository.com/artifact/org.keycloak/keycloak-kerberos-federation/24.0.4 + group_id: org.keycloak + artifact_id: keycloak-kerberos-federation + version: 24.0.4 # optional + # username: myUser # optional + # password: myPAT # optional keycloak_quarkus_policies: - name: "xato-net-10-million-passwords.txt" url: "https://github.com/danielmiessler/SecLists/raw/master/Passwords/xato-net-10-million-passwords.txt" From d87c8ca8acba5695253f91dbd39794632cc75a0c Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 14 May 2024 10:12:58 +0200 Subject: [PATCH 266/376] wip --- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index c5f5138..b630d6a 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -391,7 +391,7 @@ argument_specs: default: 10 type: 'int' keycloak_quarkus_providers: - description: "List of provider definition dicts: { 'id': str, 'spi': str, 'url': str, 'default': bool, 'properties': list of key/value }" + description: "List of provider definition dicts: { 'id': str, 'spi': str, 'url': str, 'default': bool, 'properties': list of key/value TODO:add maven}" default: [] type: "list" keycloak_quarkus_supported_policy_types: From 6d01ffbb7796da35d91713913e44f6f6dd411e22 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 14 May 2024 11:10:38 +0200 Subject: [PATCH 267/376] Close #228: add support for custom env vars in sysconfig file --- roles/keycloak_quarkus/README.md | 3 ++- roles/keycloak_quarkus/defaults/main.yml | 1 + roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/tasks/prereqs.yml | 10 ++++++++++ roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 | 5 +++++ 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 47d5a21..f8f9899 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -38,7 +38,8 @@ Role Defaults |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | |`keycloak_quarkus_java_heap_opts`| Heap memory JVM setting | `-Xms1024m -Xmx2048m` | |`keycloak_quarkus_java_jvm_opts`| Other JVM settings | same as keycloak | -|`keycloak_quarkus_java_opts`| JVM arguments; if overriden, it takes precedence over `keycloak_quarkus_java_*` | `{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}` | +|`keycloak_quarkus_java_opts`| JVM arguments; if overridden, it takes precedence over `keycloak_quarkus_java_*` | `{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}` | +|`keycloak_quarkus_additional_env_vars` | List of additional env variables of { key: str, value: str} to be put in sysconfig file | `[]` | |`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | | |`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | | |`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 8a4f9f1..d61cfff 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -44,6 +44,7 @@ keycloak_quarkus_java_jvm_opts: "-XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512" keycloak_quarkus_java_opts: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}" +keycloak_quarkus_additional_env_vars: [] ### TLS/HTTPS configuration keycloak_quarkus_https_key_file_enabled: false diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index c5f5138..c8cece8 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -201,6 +201,10 @@ argument_specs: default: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}" description: "JVM arguments, by default heap_opts + jvm_opts, if overriden it takes precedence over them" type: "str" + keycloak_quarkus_additional_env_vars: + default: "[]" + description: "List of additional env variables of { key: str, value: str} to be put in sysconfig file" + type: "list" keycloak_quarkus_ha_enabled: default: false description: "Enable auto configuration for database backend, clustering and remote caches on infinispan" diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 1e422a7..0229036 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -75,3 +75,13 @@ quiet: true fail_msg: "Policy definition is incorrect: `name` and one of `url` are mandatory, `type` needs to be left empty or one of {{ keycloak_quarkus_supported_policy_types }}." loop: "{{ keycloak_quarkus_policies }}" + +- name: "Validate additional env variables" + ansible.builtin.assert: + that: + - item.key is defined and item.key | length > 0 + - item.value is defined and item.value | length > 0 + quiet: true + fail_msg: "Additional env variable definition is incorrect: `key` and `value` are mandatory." + no_log: true + loop: "{{ keycloak_quarkus_additional_env_vars }}" diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index ef27d27..2c260a3 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -8,3 +8,8 @@ KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' PATH={{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }} JAVA_OPTS={{ keycloak_quarkus_java_opts }} + +# Custom ENV variables +{% for env in keycloak_quarkus_additional_env_vars %} +{{ env.key }}={{ env.value }} +{% endfor %} From 26316ddc506872b794b48f1c3edf882a94490b1d Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 14 May 2024 11:54:45 +0200 Subject: [PATCH 268/376] #222: add support for local providers to be uploaded --- molecule/quarkus/converge.yml | 2 ++ roles/keycloak_quarkus/README.md | 11 +++++++++-- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- roles/keycloak_quarkus/tasks/install.yml | 11 +++++++++++ roles/keycloak_quarkus/tasks/prereqs.yml | 4 ++-- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 6186af4..2fa1ceb 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -39,6 +39,8 @@ version: 24.0.4 # optional # username: myUser # optional # password: myPAT # optional + # - id: my-static-theme + # local_path: /tmp/my-static-theme.jar keycloak_quarkus_policies: - name: "xato-net-10-million-passwords.txt" url: "https://github.com/danielmiessler/SecLists/raw/master/Passwords/xato-net-10-million-passwords.txt" diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 028097c..28f81aa 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -178,15 +178,22 @@ Role Defaults |:---------|:------------|:--------| |`keycloak_quarkus_providers`| List of provider definitions; see below | `[]` | +Providers support different sources: + +* `url`: http download for SPIs not requiring authentication +* `maven`: maven download for SPIs hosted publicly on Apache Maven Central or private Maven repositories like Github Maven requiring authentication +* `local_path`: static SPIs to be uploaded + Provider definition: ```yaml keycloak_quarkus_providers: - - id: http-client # required - spi: connections # required if neither url nor maven are specified + - id: http-client # required; "{{ id }}.jar" identifies the file name on RHBK + spi: connections # required if neither url, local_path nor maven are specified; required for setting properties default: true # optional, whether to set default for spi, default false restart: true # optional, whether to restart, default true url: https://.../.../custom_spi.jar # optional, url for download via http + local_path: my_theme_spi.jar # optional, path on local controller for SPI to be uploaded maven: # optional, for download using maven repository_url: https://maven.pkg.github.com/OWNER/REPOSITORY # optional, maven repo url group_id: my.group # optional, maven group id diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index b630d6a..f4c9f51 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -391,7 +391,7 @@ argument_specs: default: 10 type: 'int' keycloak_quarkus_providers: - description: "List of provider definition dicts: { 'id': str, 'spi': str, 'url': str, 'default': bool, 'properties': list of key/value TODO:add maven}" + description: "List of provider definition dicts: { 'id': str, 'spi': str, 'url': str, 'local_path': str, 'maven': { 'repository_url': str, 'group_id': str, 'artifact_id': str, 'version': str, 'username': str, optional, 'password': str, optional }, 'default': bool, 'properties': list of key/value }" default: [] type: "list" keycloak_quarkus_supported_policy_types: diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 8d604e6..6c8b31d 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -256,6 +256,17 @@ when: item.maven is defined no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" +- name: "Upload local SPIs" + ansible.builtin.copy: + src: "{{ item.local_path}}" + dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar" + owner: "{{ keycloak.service_user }}" + group: "{{ keycloak.service_group }}" + mode: '0640' + become: true + loop: "{{ keycloak_quarkus_providers }}" + when: item.local_path is defined + - name: Ensure required folder structure for policies exists ansible.builtin.file: path: "{{ keycloak.home }}/data/{{ item | lower }}" diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 064cc10..12f9b23 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -61,9 +61,9 @@ ansible.builtin.assert: that: - item.id is defined and item.id | length > 0 - - (item.spi is defined and item.spi | length > 0) or (item.url is defined and item.url | length > 0) or (item.maven is defined and item.maven.repository_url is defined and item.maven.repository_url | length > 0 and item.maven.group_id is defined and item.maven.group_id | length > 0 and item.maven.artifact_id is defined and item.maven.artifact_id | length > 0) + - (item.spi is defined and item.spi | length > 0) or (item.url is defined and item.url | length > 0) or (item.maven is defined and item.maven.repository_url is defined and item.maven.repository_url | length > 0 and item.maven.group_id is defined and item.maven.group_id | length > 0 and item.maven.artifact_id is defined and item.maven.artifact_id | length > 0) or (item.local_path is defined and item.local_path | length > 0) quiet: true - fail_msg: "Providers definition is incorrect; `id` and one of `spi`, `url`, or `maven` are mandatory. `key` and `value` are mandatory for each property" + fail_msg: "Providers definition is incorrect; `id` and one of `spi`, `url`, `local_path`, or `maven` are mandatory. `key` and `value` are mandatory for each property" loop: "{{ keycloak_quarkus_providers }}" - name: "Validate policies" From d2ece93c12237459901928e163a0127f82b94235 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 14 May 2024 20:28:14 +0200 Subject: [PATCH 269/376] #222 Migrate to middleware_automation.common.maven_artifact --- requirements.txt | 2 +- requirements.yml | 2 +- roles/keycloak_quarkus/README.md | 7 +++---- roles/keycloak_quarkus/tasks/install.yml | 6 +++--- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/requirements.txt b/requirements.txt index a91d12a..5de7845 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,4 @@ # pip install -r requirements.txt # netaddr -lxml # for community.general.maven_artifact \ No newline at end of file +lxml # for middleware_automation.common.maven_artifact \ No newline at end of file diff --git a/requirements.yml b/requirements.yml index 10150ad..06e5714 100644 --- a/requirements.yml +++ b/requirements.yml @@ -1,5 +1,5 @@ --- collections: - name: middleware_automation.common + version: ">=1.2.1" - name: ansible.posix - - name: community.general # for `maven_artifact` diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 28f81aa..3e4ce6d 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -21,7 +21,6 @@ The roles depends on: * [middleware_automation.common](https://github.com/ansible-middleware/common) * [ansible-posix](https://docs.ansible.com/ansible/latest/collections/ansible/posix/index.html) -* [community.general](https://docs.ansible.com/ansible/latest/collections/community/general/index.html) To install all the dependencies via galaxy: @@ -180,9 +179,9 @@ Role Defaults Providers support different sources: -* `url`: http download for SPIs not requiring authentication -* `maven`: maven download for SPIs hosted publicly on Apache Maven Central or private Maven repositories like Github Maven requiring authentication -* `local_path`: static SPIs to be uploaded +* `url`: http download for providers not requiring authentication +* `maven`: maven download for providers hosted publicly on Apache Maven Central or private Maven repositories like Github Maven requiring authentication +* `local_path`: static providers to be uploaded Provider definition: diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 6c8b31d..ced4191 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -229,7 +229,7 @@ # this requires the `lxml` package to be installed; we redirect this step to localhost such that we do need to install it on the remote hosts - name: "Download custom providers to localhost using maven" - community.general.maven_artifact: + middleware_automation.common.maven_artifact: repository_url: "{{ item.maven.repository_url }}" group_id: "{{ item.maven.group_id }}" artifact_id: "{{ item.maven.artifact_id }}" @@ -244,7 +244,7 @@ no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or not item.restart else [] }}" -- name: "Upload local maven SPIs" +- name: "Upload local maven providers" ansible.builtin.copy: src: "{{ local_path.stat.path }}/{{ item.id }}.jar" dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar" @@ -256,7 +256,7 @@ when: item.maven is defined no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" -- name: "Upload local SPIs" +- name: "Upload local providers" ansible.builtin.copy: src: "{{ item.local_path}}" dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar" From 5adb28dcd83c217e059f5775fa80ac9a9cc12a9d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 15 May 2024 09:22:45 +0200 Subject: [PATCH 270/376] Bump to 2.3.0 --- galaxy.yml | 4 ++-- github.json | 0 2 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 github.json diff --git a/galaxy.yml b/galaxy.yml index 1e6fd20..da8794c 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.2.3" +version: "2.3.0" readme: README.md authors: - Romain Pelisse @@ -26,7 +26,7 @@ tags: - middleware - a4mw dependencies: - "middleware_automation.common": ">=1.1.0" + "middleware_automation.common": ">=1.2.1" "ansible.posix": ">=1.4.0" repository: https://github.com/ansible-middleware/keycloak documentation: https://ansible-middleware.github.io/keycloak diff --git a/github.json b/github.json deleted file mode 100644 index e69de29..0000000 From d57be1f188bec5bdf886605dad8581dfc158db94 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 14 May 2024 13:59:51 +0200 Subject: [PATCH 271/376] Close #182, #221: improve restart handler logic --- roles/keycloak_quarkus/tasks/restart.yml | 43 ++++++++++++++++++++---- roles/keycloak_quarkus/vars/main.yml | 2 +- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/roles/keycloak_quarkus/tasks/restart.yml b/roles/keycloak_quarkus/tasks/restart.yml index 77e1099..4b43ac8 100644 --- a/roles/keycloak_quarkus/tasks/restart.yml +++ b/roles/keycloak_quarkus/tasks/restart.yml @@ -1,9 +1,38 @@ --- -- name: "Restart and enable {{ keycloak.service_name }} service" +- name: Ensure only one service at a time gets rebooted, to ensure replication of distributed ispn caches throttle: 1 - ansible.builtin.systemd: - name: keycloak - enabled: true - state: restarted - daemon_reload: true - become: true + block: + - name: "Restart and enable {{ keycloak.service_name }} service on first host" + ansible.builtin.systemd: + name: "{{ keycloak.service_name }}" + enabled: true + state: restarted + daemon_reload: true + become: true + delegate_to: "{{ ansible_play_hosts | first }}" + run_once: true + + - name: "Wait until {{ keycloak.service_name }} service becomes active {{ keycloak.health_url }}" + ansible.builtin.uri: + url: "{{ keycloak.health_url }}" + register: keycloak_status + until: keycloak_status.status == 200 + retries: 25 + delay: 10 + delegate_to: "{{ ansible_play_hosts | first }}" + run_once: true + + - name: Pause to give distributed ispn caches time to (re-)replicate back onto first host + ansible.builtin.pause: + seconds: 15 + when: + - rhbk_ha_enabled + + - name: "Restart and enable {{ keycloak.service_name }} service on all other hosts" + ansible.builtin.systemd: + name: "{{ keycloak.service_name }}" + enabled: true + state: restarted + daemon_reload: true + become: true + when: inventory_hostname != ansible_play_hosts | first diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index fcf82f0..a5c4aaa 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,7 +4,7 @@ keycloak: # noqa var-naming this is an internal dict of interpolated values config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' \ + health_url: "{{ 'https' if keycloak_quarkus_http_enabled == False else 'http' }}://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_https_port if keycloak_quarkus_http_enabled == False else keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' \ if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" From db831fa339c6d2c8e31aba7a2c2146f080aa9234 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 15 May 2024 10:17:32 +0200 Subject: [PATCH 272/376] #182 - CR changes --- roles/keycloak_quarkus/tasks/restart.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/tasks/restart.yml b/roles/keycloak_quarkus/tasks/restart.yml index 4b43ac8..4d55189 100644 --- a/roles/keycloak_quarkus/tasks/restart.yml +++ b/roles/keycloak_quarkus/tasks/restart.yml @@ -26,7 +26,7 @@ ansible.builtin.pause: seconds: 15 when: - - rhbk_ha_enabled + - keycloak_quarkus_ha_enabled - name: "Restart and enable {{ keycloak.service_name }} service on all other hosts" ansible.builtin.systemd: From 1e9a669deab77ef65e749f9926211fe35eaea40c Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 15 May 2024 10:28:46 +0200 Subject: [PATCH 273/376] #221 - add keycloak_quarkus_health_check_url_path config option --- roles/keycloak_quarkus/README.md | 1 + roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/vars/main.yml | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index a011f29..2ba3c99 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -66,6 +66,7 @@ Role Defaults |`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | | |`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | +|`keycloak_quarkus_health_check_url_path`| Path to the health check endpoint; scheme, host and keycloak_quarkus_http_relative_path will be prepended automatically | `realms/master/.well-known/openid-configuration` | |`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` | |`keycloak_quarkus_key_file_copy_enabled`| Enable copy of key file to target host | `False` | |`keycloak_quarkus_key_content`| Content of the TLS private key. Use `"{{ lookup('file', 'server.key.pem') }}"` to lookup a file. | `""` | diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 11d928f..6936fa2 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -104,6 +104,10 @@ argument_specs: default: 8080 description: "HTTP port" type: "int" + keycloak_quarkus_health_check_url_path: + default: "realms/master/.well-known/openid-configuration" + description: "Path to the health check endpoint; scheme, host and keycloak_quarkus_http_relative_path will be prepended automatically" + type: "str" keycloak_quarkus_https_key_file_enabled: default: false description: "Enable configuration of HTTPS via files in PEM format" diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index a5c4aaa..e59af55 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -5,7 +5,7 @@ keycloak: # noqa var-naming this is an internal dict of interpolated values bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" health_url: "{{ 'https' if keycloak_quarkus_http_enabled == False else 'http' }}://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_https_port if keycloak_quarkus_http_enabled == False else keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' \ - if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration" + if keycloak_quarkus_http_relative_path | length > 1 else '' }}{{ keycloak_quarkus_health_check_url_path | default('realms/master/.well-known/openid-configuration') }}" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" From 2d573c2b626e348130b921ad827ed3a222daee75 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 15 May 2024 13:34:29 +0200 Subject: [PATCH 274/376] Add restart strategies, and allow custom task include Co-authored-by: Helmut Wolf Co-authored-by: Guido Grazioli --- roles/keycloak_quarkus/defaults/main.yml | 5 ++ roles/keycloak_quarkus/handlers/main.yml | 3 +- .../keycloak_quarkus/meta/argument_specs.yml | 22 +++++++- roles/keycloak_quarkus/tasks/install.yml | 4 +- roles/keycloak_quarkus/tasks/prereqs.yml | 18 +++++-- roles/keycloak_quarkus/tasks/restart.yml | 51 ++++++------------- roles/keycloak_quarkus/tasks/restart/none.yml | 4 ++ .../keycloak_quarkus/tasks/restart/serial.yml | 8 +++ .../tasks/restart/verify_first.yml | 34 +++++++++++++ 9 files changed, 104 insertions(+), 45 deletions(-) create mode 100644 roles/keycloak_quarkus/tasks/restart/none.yml create mode 100644 roles/keycloak_quarkus/tasks/restart/serial.yml create mode 100644 roles/keycloak_quarkus/tasks/restart/verify_first.yml diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index d61cfff..0dde230 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -153,3 +153,8 @@ keycloak_quarkus_ks_vault_pass: keycloak_quarkus_providers: [] keycloak_quarkus_policies: [] keycloak_quarkus_supported_policy_types: ['password-blacklists'] + +# files in restart directory (one of [ 'serial', 'none', 'verify_first' ]), or path to file when providing custom strategy +keycloak_quarkus_restart_strategy: restart/serial.yml +keycloak_quarkus_restart_health_check: "{{ keycloak_quarkus_ha_enabled }}" +keycloak_quarkus_restart_pause: 15 diff --git a/roles/keycloak_quarkus/handlers/main.yml b/roles/keycloak_quarkus/handlers/main.yml index b95d5c3..5851a71 100644 --- a/roles/keycloak_quarkus/handlers/main.yml +++ b/roles/keycloak_quarkus/handlers/main.yml @@ -7,7 +7,8 @@ ansible.builtin.include_tasks: bootstrapped.yml listen: bootstrapped - name: "Restart {{ keycloak.service_name }}" - ansible.builtin.include_tasks: restart.yml + ansible.builtin.include_tasks: + file: "{{ keycloak_quarkus_restart_strategy if keycloak_quarkus_ha_enabled else 'restart.yml' }}" listen: "restart keycloak" - name: "Print deprecation warning" ansible.builtin.fail: diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 6936fa2..01dbfb9 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -399,7 +399,13 @@ argument_specs: default: 10 type: 'int' keycloak_quarkus_providers: - description: "List of provider definition dicts: { 'id': str, 'spi': str, 'url': str, 'local_path': str, 'maven': { 'repository_url': str, 'group_id': str, 'artifact_id': str, 'version': str, 'username': str, optional, 'password': str, optional }, 'default': bool, 'properties': list of key/value }" + description: > + List of provider definition dicts: { 'id': str, 'spi': str, 'url': str, 'local_path': str, + 'maven': { + 'repository_url': str, 'group_id': str, 'artifact_id': str, 'version': str, 'username': str, optional, 'password': str, optional + }, + 'default': bool, + 'properties': list of key/value } default: [] type: "list" keycloak_quarkus_supported_policy_types: @@ -425,6 +431,20 @@ argument_specs: default: true description: "Allow the option to ignore invalid certificates when downloading JDBC drivers from a custom URL" type: "bool" + keycloak_quarkus_restart_health_check: + default: "{{ keycloak_quarkus_ha_enabled }}" + description: "Whether to wait on successful health check after restart" + type: "bool" + keycloak_quarkus_restart_strategy: + description: > + Strategy task file for restarting in HA, one of [ 'serial', 'none', 'verify_first' ] below, or path to + file when providing custom strategy + default: "restart/serial.yml" + type: "str" + keycloak_quarkus_restart_pause: + description: "Seconds to wait between restarts in HA strategy" + default: 15 + type: int downstream: options: rhbk_version: diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index ced4191..7745031 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -258,7 +258,7 @@ - name: "Upload local providers" ansible.builtin.copy: - src: "{{ item.local_path}}" + src: "{{ item.local_path }}" dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" @@ -280,7 +280,7 @@ - name: "Install custom policies" ansible.builtin.get_url: url: "{{ item.url }}" - dest: "{{ keycloak.home }}/data/{{ item.type|default(keycloak_quarkus_supported_policy_types | first) | lower }}/{{ item.name }}" + dest: "{{ keycloak.home }}/data/{{ item.type | default(keycloak_quarkus_supported_policy_types | first) | lower }}/{{ item.name }}" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: '0640' diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index d901c71..220f65b 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -59,11 +59,18 @@ - name: "Validate providers" ansible.builtin.assert: - that: - - item.id is defined and item.id | length > 0 - - (item.spi is defined and item.spi | length > 0) or (item.url is defined and item.url | length > 0) or (item.maven is defined and item.maven.repository_url is defined and item.maven.repository_url | length > 0 and item.maven.group_id is defined and item.maven.group_id | length > 0 and item.maven.artifact_id is defined and item.maven.artifact_id | length > 0) or (item.local_path is defined and item.local_path | length > 0) + that: > + item.id is defined and item.id | length > 0 and + ( (item.spi is defined and item.spi | length > 0) or + (item.url is defined and item.url | length > 0) or + ( item.maven is defined and item.maven.repository_url is defined and item.maven.repository_url | length > 0 and + item.maven.group_id is defined and item.maven.group_id | length > 0 and + item.maven.artifact_id is defined and item.maven.artifact_id | length > 0) or + (item.local_path is defined and item.local_path | length > 0) + ) quiet: true - fail_msg: "Providers definition is incorrect; `id` and one of `spi`, `url`, `local_path`, or `maven` are mandatory. `key` and `value` are mandatory for each property" + fail_msg: > + Providers definition incorrect; `id` and one of `spi`, `url`, `local_path`, or `maven` are mandatory. `key` and `value` are mandatory for each property loop: "{{ keycloak_quarkus_providers }}" - name: "Validate policies" @@ -73,7 +80,8 @@ - item.url is defined and item.url | length > 0 - item.type is not defined or item.type | lower in keycloak_quarkus_supported_policy_types quiet: true - fail_msg: "Policy definition is incorrect: `name` and one of `url` are mandatory, `type` needs to be left empty or one of {{ keycloak_quarkus_supported_policy_types }}." + fail_msg: > + Policy definition is incorrect: `name` and one of `url` are mandatory, `type` needs to be left empty or one of {{ keycloak_quarkus_supported_policy_types }}. loop: "{{ keycloak_quarkus_policies }}" - name: "Validate additional env variables" diff --git a/roles/keycloak_quarkus/tasks/restart.yml b/roles/keycloak_quarkus/tasks/restart.yml index 4d55189..9255114 100644 --- a/roles/keycloak_quarkus/tasks/restart.yml +++ b/roles/keycloak_quarkus/tasks/restart.yml @@ -1,38 +1,17 @@ --- -- name: Ensure only one service at a time gets rebooted, to ensure replication of distributed ispn caches - throttle: 1 - block: - - name: "Restart and enable {{ keycloak.service_name }} service on first host" - ansible.builtin.systemd: - name: "{{ keycloak.service_name }}" - enabled: true - state: restarted - daemon_reload: true - become: true - delegate_to: "{{ ansible_play_hosts | first }}" - run_once: true +- name: "Restart and enable {{ keycloak.service_name }} service" + ansible.builtin.systemd: + name: "{{ keycloak.service_name }}" + enabled: true + state: restarted + daemon_reload: true + become: true - - name: "Wait until {{ keycloak.service_name }} service becomes active {{ keycloak.health_url }}" - ansible.builtin.uri: - url: "{{ keycloak.health_url }}" - register: keycloak_status - until: keycloak_status.status == 200 - retries: 25 - delay: 10 - delegate_to: "{{ ansible_play_hosts | first }}" - run_once: true - - - name: Pause to give distributed ispn caches time to (re-)replicate back onto first host - ansible.builtin.pause: - seconds: 15 - when: - - keycloak_quarkus_ha_enabled - - - name: "Restart and enable {{ keycloak.service_name }} service on all other hosts" - ansible.builtin.systemd: - name: "{{ keycloak.service_name }}" - enabled: true - state: restarted - daemon_reload: true - become: true - when: inventory_hostname != ansible_play_hosts | first +- name: "Wait until {{ keycloak.service_name }} service becomes active {{ keycloak.health_url }}" + ansible.builtin.uri: + url: "{{ keycloak.health_url }}" + register: keycloak_status + until: keycloak_status.status == 200 + retries: 25 + delay: 10 + when: keycloak_quarkus_restart_health_check diff --git a/roles/keycloak_quarkus/tasks/restart/none.yml b/roles/keycloak_quarkus/tasks/restart/none.yml new file mode 100644 index 0000000..d048959 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/restart/none.yml @@ -0,0 +1,4 @@ +--- +- name: "Display message" + ansible.builtin.debug: + msg: "keycloak_quarkus_restart_strategy is none, skipping restart" diff --git a/roles/keycloak_quarkus/tasks/restart/serial.yml b/roles/keycloak_quarkus/tasks/restart/serial.yml new file mode 100644 index 0000000..74e8e3b --- /dev/null +++ b/roles/keycloak_quarkus/tasks/restart/serial.yml @@ -0,0 +1,8 @@ +--- +- name: "Restart services in serial, with optional healtch check (keycloak_quarkus_restart_health_check)" + throttle: 1 + loop: "{{ ansible_play_hosts }}" + block: + - name: "Restart and enable {{ keycloak.service_name }} service on first host" + ansible.builtin.include_tasks: ../restart.yml + delegate_to: "{{ item }}" diff --git a/roles/keycloak_quarkus/tasks/restart/verify_first.yml b/roles/keycloak_quarkus/tasks/restart/verify_first.yml new file mode 100644 index 0000000..64e2f53 --- /dev/null +++ b/roles/keycloak_quarkus/tasks/restart/verify_first.yml @@ -0,0 +1,34 @@ +--- +- name: Verify first restarted service with health URL, then rest in parallel + block: + - name: "Restart and enable {{ keycloak.service_name }} service on first host" + ansible.builtin.systemd: + name: "{{ keycloak.service_name }}" + enabled: true + state: restarted + daemon_reload: true + become: true + delegate_to: "{{ ansible_play_hosts | first }}" + run_once: true + + - name: "Wait until {{ keycloak.service_name }} service becomes active {{ keycloak.health_url }}" + ansible.builtin.uri: + url: "{{ keycloak.health_url }}" + register: keycloak_status + until: keycloak_status.status == 200 + retries: 25 + delay: 10 + delegate_to: "{{ ansible_play_hosts | first }}" + run_once: true + + - name: Pause to give distributed ispn caches time to (re-)replicate back onto first host + ansible.builtin.pause: + seconds: "{{ keycloak_quarkus_restart_pause }}" + when: + - keycloak_quarkus_ha_enabled + + - name: "Restart and enable {{ keycloak.service_name }} service on other hosts" + ansible.builtin.include_tasks: ../restart.yml + delegate_to: "{{ item }}" + loop: "{{ ansible_play_hosts }}" + when: inventory_hostname != ansible_play_hosts | first From c22389c86fabce46d98bab90f8761586b97e000a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 15 May 2024 15:58:21 +0200 Subject: [PATCH 275/376] address review reqs --- roles/keycloak_quarkus/README.md | 3 +++ roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 6 +++--- roles/keycloak_quarkus/tasks/restart.yml | 6 ++++++ roles/keycloak_quarkus/tasks/restart/serial.yml | 9 ++++++--- .../{verify_first.yml => serial_then_parallel.yml} | 11 +++++++---- 6 files changed, 26 insertions(+), 11 deletions(-) rename roles/keycloak_quarkus/tasks/restart/{verify_first.yml => serial_then_parallel.yml} (85%) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 2ba3c99..a9dbea0 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -101,6 +101,9 @@ Role Defaults |`keycloak_quarkus_systemd_wait_for_log` | Whether systemd unit should wait for service to be up in logs | `false` | |`keycloak_quarkus_systemd_wait_for_timeout`| How long to wait for service to be alive (seconds) | `60` | |`keycloak_quarkus_systemd_wait_for_delay`| Activation delay for service systemd unit (seconds) | `10` | +|`keycloak_quarkus_restart_strategy`| Strategy task file for restarting in HA (one of provided restart/['serial.yml','none.yml','serial_then_parallel.yml']) or path to file when providing custom strategy | `restart/serial.yml` | +|`keycloak_quarkus_restart_health_check`| Whether to wait for successful health check after restart | `{{ keycloak_quarkus_ha_enabled }}` | +|`keycloak_quarkus_restart_pause`| Seconds to wait between restarts in HA strategy | `15` | #### Hostname configuration diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 0dde230..c152a20 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -154,7 +154,7 @@ keycloak_quarkus_providers: [] keycloak_quarkus_policies: [] keycloak_quarkus_supported_policy_types: ['password-blacklists'] -# files in restart directory (one of [ 'serial', 'none', 'verify_first' ]), or path to file when providing custom strategy +# files in restart directory (one of [ 'serial', 'none', 'serial_then_parallel' ]), or path to file when providing custom strategy keycloak_quarkus_restart_strategy: restart/serial.yml keycloak_quarkus_restart_health_check: "{{ keycloak_quarkus_ha_enabled }}" keycloak_quarkus_restart_pause: 15 diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 01dbfb9..3e06525 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -433,12 +433,12 @@ argument_specs: type: "bool" keycloak_quarkus_restart_health_check: default: "{{ keycloak_quarkus_ha_enabled }}" - description: "Whether to wait on successful health check after restart" + description: "Whether to wait for successful health check after restart" type: "bool" keycloak_quarkus_restart_strategy: description: > - Strategy task file for restarting in HA, one of [ 'serial', 'none', 'verify_first' ] below, or path to - file when providing custom strategy + Strategy task file for restarting in HA, one of restart/[ 'serial', 'none', 'serial_then_parallel' ].yml, or path to + file when providing custom strategy; when keycloak_quarkus_ha_enabled and keycloak_quarkus_restart_health_check == true default: "restart/serial.yml" type: "str" keycloak_quarkus_restart_pause: diff --git a/roles/keycloak_quarkus/tasks/restart.yml b/roles/keycloak_quarkus/tasks/restart.yml index 9255114..bcb8c1d 100644 --- a/roles/keycloak_quarkus/tasks/restart.yml +++ b/roles/keycloak_quarkus/tasks/restart.yml @@ -15,3 +15,9 @@ retries: 25 delay: 10 when: keycloak_quarkus_restart_health_check + +- name: Pause to give distributed ispn caches time to (re-)replicate back onto first host + ansible.builtin.pause: + seconds: "{{ keycloak_quarkus_restart_pause }}" + when: + - keycloak_quarkus_ha_enabled diff --git a/roles/keycloak_quarkus/tasks/restart/serial.yml b/roles/keycloak_quarkus/tasks/restart/serial.yml index 74e8e3b..d98dbf9 100644 --- a/roles/keycloak_quarkus/tasks/restart/serial.yml +++ b/roles/keycloak_quarkus/tasks/restart/serial.yml @@ -3,6 +3,9 @@ throttle: 1 loop: "{{ ansible_play_hosts }}" block: - - name: "Restart and enable {{ keycloak.service_name }} service on first host" - ansible.builtin.include_tasks: ../restart.yml - delegate_to: "{{ item }}" + - name: "Restart and enable {{ keycloak.service_name }} service on {{ item }}" + ansible.builtin.include_tasks: + file: ../restart.yml + apply: + delegate_to: "{{ item }}" + run_once: true diff --git a/roles/keycloak_quarkus/tasks/restart/verify_first.yml b/roles/keycloak_quarkus/tasks/restart/serial_then_parallel.yml similarity index 85% rename from roles/keycloak_quarkus/tasks/restart/verify_first.yml rename to roles/keycloak_quarkus/tasks/restart/serial_then_parallel.yml index 64e2f53..372a302 100644 --- a/roles/keycloak_quarkus/tasks/restart/verify_first.yml +++ b/roles/keycloak_quarkus/tasks/restart/serial_then_parallel.yml @@ -1,5 +1,5 @@ --- -- name: Verify first restarted service with health URL, then rest in parallel +- name: Verify first restarted service with health URL, then rest restart in parallel block: - name: "Restart and enable {{ keycloak.service_name }} service on first host" ansible.builtin.systemd: @@ -28,7 +28,10 @@ - keycloak_quarkus_ha_enabled - name: "Restart and enable {{ keycloak.service_name }} service on other hosts" - ansible.builtin.include_tasks: ../restart.yml - delegate_to: "{{ item }}" - loop: "{{ ansible_play_hosts }}" + ansible.builtin.systemd: + name: "{{ keycloak.service_name }}" + enabled: true + state: restarted + daemon_reload: true + become: true when: inventory_hostname != ansible_play_hosts | first From fdcf1b2ed2d45f696f20263a267cc637a21a5bf8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 15 May 2024 19:53:33 +0200 Subject: [PATCH 276/376] Add molecule scenario for HA restart --- .github/workflows/ci.yml | 2 +- .gitignore | 1 + molecule/quarkus/converge.yml | 2 +- molecule/quarkus_ha/converge.yml | 29 + molecule/quarkus_ha/molecule.yml | 79 ++ .../quarkus_ha/postgresql/postgresql.conf | 750 ++++++++++++++++++ molecule/quarkus_ha/prepare.yml | 44 + molecule/quarkus_ha/roles | 1 + molecule/quarkus_ha/verify.yml | 86 ++ .../keycloak_quarkus/tasks/restart/serial.yml | 4 +- .../templates/quarkus.properties.j2 | 2 +- 11 files changed, 995 insertions(+), 5 deletions(-) create mode 100644 molecule/quarkus_ha/converge.yml create mode 100644 molecule/quarkus_ha/molecule.yml create mode 100644 molecule/quarkus_ha/postgresql/postgresql.conf create mode 100644 molecule/quarkus_ha/prepare.yml create mode 120000 molecule/quarkus_ha/roles create mode 100644 molecule/quarkus_ha/verify.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d5cac41..0927320 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode", "quarkus_upgrade", "debian" ] + [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode", "quarkus_upgrade", "debian", "quarkus_ha" ] diff --git a/.gitignore b/.gitignore index e1daa92..f2ffea4 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ docs/_build/ *.retry changelogs/.plugin-cache.yaml *.pem +*.key diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 2fa1ceb..da0f3dc 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -7,7 +7,7 @@ keycloak_realm: TestRealm keycloak_quarkus_host: instance keycloak_quarkus_log: file - keycloak_quarkus_log_level: debug + keycloak_quarkus_log_level: info keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_key_file_copy_enabled: true keycloak_quarkus_key_content: "{{ lookup('file', 'key.pem') }}" diff --git a/molecule/quarkus_ha/converge.yml b/molecule/quarkus_ha/converge.yml new file mode 100644 index 0000000..2434e65 --- /dev/null +++ b/molecule/quarkus_ha/converge.yml @@ -0,0 +1,29 @@ +--- +- name: Converge + hosts: keycloak + vars: + keycloak_quarkus_admin_pass: "remembertochangeme" + keycloak_admin_password: "remembertochangeme" + keycloak_realm: TestRealm + keycloak_quarkus_host: "{{ inventory_hostname }}" + keycloak_quarkus_log: file + keycloak_quarkus_log_level: info + keycloak_quarkus_https_key_file_enabled: true + keycloak_quarkus_key_file_copy_enabled: true + keycloak_quarkus_key_content: "{{ lookup('file', inventory_hostname + '.key') }}" + keycloak_quarkus_cert_file_copy_enabled: true + keycloak_quarkus_cert_file_src: "{{ inventory_hostname }}.pem" + keycloak_quarkus_ks_vault_enabled: true + keycloak_quarkus_ks_vault_file: "/opt/keycloak/vault/keystore.p12" + keycloak_quarkus_ks_vault_pass: keystorepassword + keycloak_quarkus_systemd_wait_for_port: true + keycloak_quarkus_systemd_wait_for_timeout: 20 + keycloak_quarkus_systemd_wait_for_delay: 2 + keycloak_quarkus_systemd_wait_for_log: true + keycloak_quarkus_ha_enabled: true + keycloak_quarkus_restart_strategy: restart/serial.yml + keycloak_quarkus_db_user: keycloak + keycloak_quarkus_db_pass: mysecretpass + keycloak_quarkus_jdbc_url: jdbc:postgresql://postgres:5432/keycloak + roles: + - role: keycloak_quarkus diff --git a/molecule/quarkus_ha/molecule.yml b/molecule/quarkus_ha/molecule.yml new file mode 100644 index 0000000..8e07e0f --- /dev/null +++ b/molecule/quarkus_ha/molecule.yml @@ -0,0 +1,79 @@ +--- +driver: + name: docker +platforms: + - name: instance1 + image: registry.access.redhat.com/ubi9/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + groups: + - keycloak + networks: + - name: rhbk + port_bindings: + - "8080/tcp" + - "8443/tcp" + - name: instance2 + image: registry.access.redhat.com/ubi9/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + groups: + - keycloak + networks: + - name: rhbk + port_bindings: + - "8080/tcp" + - "8443/tcp" + - name: postgres + image: ubuntu/postgres:14-22.04_beta + pre_build_image: true + privileged: true + command: postgres + groups: + - database + networks: + - name: rhbk + port_bindings: + - "5432/tcp" + mounts: + - type: bind + target: /etc/postgresql/postgresql.conf + source: ${PWD}/molecule/quarkus_ha/postgresql/postgresql.conf + env: + POSTGRES_USER: keycloak + POSTGRES_PASSWORD: mysecretpass + POSTGRES_DB: keycloak + POSTGRES_HOST_AUTH_METHOD: trust +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + ssh_connection: + pipelining: false + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + env: + ANSIBLE_FORCE_COLOR: "true" +verifier: + name: ansible +scenario: + test_sequence: + - cleanup + - destroy + - create + - prepare + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/quarkus_ha/postgresql/postgresql.conf b/molecule/quarkus_ha/postgresql/postgresql.conf new file mode 100644 index 0000000..d702576 --- /dev/null +++ b/molecule/quarkus_ha/postgresql/postgresql.conf @@ -0,0 +1,750 @@ +# ----------------------------- +# PostgreSQL configuration file +# ----------------------------- +# +# This file consists of lines of the form: +# +# name = value +# +# (The "=" is optional.) Whitespace may be used. Comments are introduced with +# "#" anywhere on a line. The complete list of parameter names and allowed +# values can be found in the PostgreSQL documentation. +# +# The commented-out settings shown in this file represent the default values. +# Re-commenting a setting is NOT sufficient to revert it to the default value; +# you need to reload the server. +# +# This file is read on server startup and when the server receives a SIGHUP +# signal. If you edit the file on a running system, you have to SIGHUP the +# server for the changes to take effect, run "pg_ctl reload", or execute +# "SELECT pg_reload_conf()". Some parameters, which are marked below, +# require a server shutdown and restart to take effect. +# +# Any parameter can also be given as a command-line option to the server, e.g., +# "postgres -c log_connections=on". Some parameters can be changed at run time +# with the "SET" SQL command. +# +# Memory units: kB = kilobytes Time units: ms = milliseconds +# MB = megabytes s = seconds +# GB = gigabytes min = minutes +# TB = terabytes h = hours +# d = days + + +#------------------------------------------------------------------------------ +# FILE LOCATIONS +#------------------------------------------------------------------------------ + +# The default values of these variables are driven from the -D command-line +# option or PGDATA environment variable, represented here as ConfigDir. + +#data_directory = 'ConfigDir' # use data in another directory + # (change requires restart) +#hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file + # (change requires restart) +#ident_file = 'ConfigDir/pg_ident.conf' # ident configuration file + # (change requires restart) + +# If external_pid_file is not explicitly set, no extra PID file is written. +#external_pid_file = '' # write an extra PID file + # (change requires restart) + + +#------------------------------------------------------------------------------ +# CONNECTIONS AND AUTHENTICATION +#------------------------------------------------------------------------------ + +# - Connection Settings - + +listen_addresses = '*' # what IP address(es) to listen on; + # comma-separated list of addresses; + # defaults to 'localhost'; use '*' for all + # (change requires restart) +#port = 5432 # (change requires restart) +#max_connections = 100 # (change requires restart) +#superuser_reserved_connections = 3 # (change requires restart) +#unix_socket_directories = '/tmp' # comma-separated list of directories + # (change requires restart) +#unix_socket_group = '' # (change requires restart) +#unix_socket_permissions = 0777 # begin with 0 to use octal notation + # (change requires restart) +#bonjour = off # advertise server via Bonjour + # (change requires restart) +#bonjour_name = '' # defaults to the computer name + # (change requires restart) + +# - TCP settings - +# see "man 7 tcp" for details + +#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; + # 0 selects the system default +#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; + # 0 selects the system default +#tcp_keepalives_count = 0 # TCP_KEEPCNT; + # 0 selects the system default +#tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds; + # 0 selects the system default + +# - Authentication - + +#authentication_timeout = 1min # 1s-600s +#password_encryption = md5 # md5 or scram-sha-256 +#db_user_namespace = off + +# GSSAPI using Kerberos +#krb_server_keyfile = '' +#krb_caseins_users = off + +# - SSL - + +#ssl = off +#ssl_ca_file = '' +#ssl_cert_file = 'server.crt' +#ssl_crl_file = '' +#ssl_key_file = 'server.key' +#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers +#ssl_prefer_server_ciphers = on +#ssl_ecdh_curve = 'prime256v1' +#ssl_min_protocol_version = 'TLSv1' +#ssl_max_protocol_version = '' +#ssl_dh_params_file = '' +#ssl_passphrase_command = '' +#ssl_passphrase_command_supports_reload = off + + +#------------------------------------------------------------------------------ +# RESOURCE USAGE (except WAL) +#------------------------------------------------------------------------------ + +# - Memory - + +#shared_buffers = 32MB # min 128kB + # (change requires restart) +#huge_pages = try # on, off, or try + # (change requires restart) +#temp_buffers = 8MB # min 800kB +#max_prepared_transactions = 0 # zero disables the feature + # (change requires restart) +# Caution: it is not advisable to set max_prepared_transactions nonzero unless +# you actively intend to use prepared transactions. +#work_mem = 4MB # min 64kB +#maintenance_work_mem = 64MB # min 1MB +#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem +#max_stack_depth = 2MB # min 100kB +#shared_memory_type = mmap # the default is the first option + # supported by the operating system: + # mmap + # sysv + # windows + # (change requires restart) +#dynamic_shared_memory_type = posix # the default is the first option + # supported by the operating system: + # posix + # sysv + # windows + # mmap + # (change requires restart) + +# - Disk - + +#temp_file_limit = -1 # limits per-process temp file space + # in kB, or -1 for no limit + +# - Kernel Resources - + +#max_files_per_process = 1000 # min 25 + # (change requires restart) + +# - Cost-Based Vacuum Delay - + +#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables) +#vacuum_cost_page_hit = 1 # 0-10000 credits +#vacuum_cost_page_miss = 10 # 0-10000 credits +#vacuum_cost_page_dirty = 20 # 0-10000 credits +#vacuum_cost_limit = 200 # 1-10000 credits + +# - Background Writer - + +#bgwriter_delay = 200ms # 10-10000ms between rounds +#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables +#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round +#bgwriter_flush_after = 0 # measured in pages, 0 disables + +# - Asynchronous Behavior - + +#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching +#max_worker_processes = 8 # (change requires restart) +#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers +#max_parallel_workers_per_gather = 2 # taken from max_parallel_workers +#parallel_leader_participation = on +#max_parallel_workers = 8 # maximum number of max_worker_processes that + # can be used in parallel operations +#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate + # (change requires restart) +#backend_flush_after = 0 # measured in pages, 0 disables + + +#------------------------------------------------------------------------------ +# WRITE-AHEAD LOG +#------------------------------------------------------------------------------ + +# - Settings - + +#wal_level = replica # minimal, replica, or logical + # (change requires restart) +#fsync = on # flush data to disk for crash safety + # (turning this off can cause + # unrecoverable data corruption) +#synchronous_commit = on # synchronization level; + # off, local, remote_write, remote_apply, or on +#wal_sync_method = fsync # the default is the first option + # supported by the operating system: + # open_datasync + # fdatasync (default on Linux) + # fsync + # fsync_writethrough + # open_sync +#full_page_writes = on # recover from partial page writes +#wal_compression = off # enable compression of full-page writes +#wal_log_hints = off # also do full page writes of non-critical updates + # (change requires restart) +#wal_init_zero = on # zero-fill new WAL files +#wal_recycle = on # recycle WAL files +#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers + # (change requires restart) +#wal_writer_delay = 200ms # 1-10000 milliseconds +#wal_writer_flush_after = 1MB # measured in pages, 0 disables + +#commit_delay = 0 # range 0-100000, in microseconds +#commit_siblings = 5 # range 1-1000 + +# - Checkpoints - + +#checkpoint_timeout = 5min # range 30s-1d +#max_wal_size = 1GB +#min_wal_size = 80MB +#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0 +#checkpoint_flush_after = 0 # measured in pages, 0 disables +#checkpoint_warning = 30s # 0 disables + +# - Archiving - + +#archive_mode = off # enables archiving; off, on, or always + # (change requires restart) +#archive_command = '' # command to use to archive a logfile segment + # placeholders: %p = path of file to archive + # %f = file name only + # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' +#archive_timeout = 0 # force a logfile segment switch after this + # number of seconds; 0 disables + +# - Archive Recovery - + +# These are only used in recovery mode. + +#restore_command = '' # command to use to restore an archived logfile segment + # placeholders: %p = path of file to restore + # %f = file name only + # e.g. 'cp /mnt/server/archivedir/%f %p' + # (change requires restart) +#archive_cleanup_command = '' # command to execute at every restartpoint +#recovery_end_command = '' # command to execute at completion of recovery + +# - Recovery Target - + +# Set these only when performing a targeted recovery. + +#recovery_target = '' # 'immediate' to end recovery as soon as a + # consistent state is reached + # (change requires restart) +#recovery_target_name = '' # the named restore point to which recovery will proceed + # (change requires restart) +#recovery_target_time = '' # the time stamp up to which recovery will proceed + # (change requires restart) +#recovery_target_xid = '' # the transaction ID up to which recovery will proceed + # (change requires restart) +#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed + # (change requires restart) +#recovery_target_inclusive = on # Specifies whether to stop: + # just after the specified recovery target (on) + # just before the recovery target (off) + # (change requires restart) +#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID + # (change requires restart) +#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown' + # (change requires restart) + + +#------------------------------------------------------------------------------ +# REPLICATION +#------------------------------------------------------------------------------ + +# - Sending Servers - + +# Set these on the master and on any standby that will send replication data. + +#max_wal_senders = 10 # max number of walsender processes + # (change requires restart) +#wal_keep_segments = 0 # in logfile segments; 0 disables +#wal_sender_timeout = 60s # in milliseconds; 0 disables + +#max_replication_slots = 10 # max number of replication slots + # (change requires restart) +#track_commit_timestamp = off # collect timestamp of transaction commit + # (change requires restart) + +# - Master Server - + +# These settings are ignored on a standby server. + +#synchronous_standby_names = '' # standby servers that provide sync rep + # method to choose sync standbys, number of sync standbys, + # and comma-separated list of application_name + # from standby(s); '*' = all +#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed + +# - Standby Servers - + +# These settings are ignored on a master server. + +#primary_conninfo = '' # connection string to sending server + # (change requires restart) +#primary_slot_name = '' # replication slot on sending server + # (change requires restart) +#promote_trigger_file = '' # file name whose presence ends recovery +#hot_standby = on # "off" disallows queries during recovery + # (change requires restart) +#max_standby_archive_delay = 30s # max delay before canceling queries + # when reading WAL from archive; + # -1 allows indefinite delay +#max_standby_streaming_delay = 30s # max delay before canceling queries + # when reading streaming WAL; + # -1 allows indefinite delay +#wal_receiver_status_interval = 10s # send replies at least this often + # 0 disables +#hot_standby_feedback = off # send info from standby to prevent + # query conflicts +#wal_receiver_timeout = 60s # time that receiver waits for + # communication from master + # in milliseconds; 0 disables +#wal_retrieve_retry_interval = 5s # time to wait before retrying to + # retrieve WAL after a failed attempt +#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery + +# - Subscribers - + +# These settings are ignored on a publisher. + +#max_logical_replication_workers = 4 # taken from max_worker_processes + # (change requires restart) +#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers + + +#------------------------------------------------------------------------------ +# QUERY TUNING +#------------------------------------------------------------------------------ + +# - Planner Method Configuration - + +#enable_bitmapscan = on +#enable_hashagg = on +#enable_hashjoin = on +#enable_indexscan = on +#enable_indexonlyscan = on +#enable_material = on +#enable_mergejoin = on +#enable_nestloop = on +#enable_parallel_append = on +#enable_seqscan = on +#enable_sort = on +#enable_tidscan = on +#enable_partitionwise_join = off +#enable_partitionwise_aggregate = off +#enable_parallel_hash = on +#enable_partition_pruning = on + +# - Planner Cost Constants - + +#seq_page_cost = 1.0 # measured on an arbitrary scale +#random_page_cost = 4.0 # same scale as above +#cpu_tuple_cost = 0.01 # same scale as above +#cpu_index_tuple_cost = 0.005 # same scale as above +#cpu_operator_cost = 0.0025 # same scale as above +#parallel_tuple_cost = 0.1 # same scale as above +#parallel_setup_cost = 1000.0 # same scale as above + +#jit_above_cost = 100000 # perform JIT compilation if available + # and query more expensive than this; + # -1 disables +#jit_inline_above_cost = 500000 # inline small functions if query is + # more expensive than this; -1 disables +#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if + # query is more expensive than this; + # -1 disables + +#min_parallel_table_scan_size = 8MB +#min_parallel_index_scan_size = 512kB +#effective_cache_size = 4GB + +# - Genetic Query Optimizer - + +#geqo = on +#geqo_threshold = 12 +#geqo_effort = 5 # range 1-10 +#geqo_pool_size = 0 # selects default based on effort +#geqo_generations = 0 # selects default based on effort +#geqo_selection_bias = 2.0 # range 1.5-2.0 +#geqo_seed = 0.0 # range 0.0-1.0 + +# - Other Planner Options - + +#default_statistics_target = 100 # range 1-10000 +#constraint_exclusion = partition # on, off, or partition +#cursor_tuple_fraction = 0.1 # range 0.0-1.0 +#from_collapse_limit = 8 +#join_collapse_limit = 8 # 1 disables collapsing of explicit + # JOIN clauses +#force_parallel_mode = off +#jit = on # allow JIT compilation +#plan_cache_mode = auto # auto, force_generic_plan or + # force_custom_plan + + +#------------------------------------------------------------------------------ +# REPORTING AND LOGGING +#------------------------------------------------------------------------------ + +# - Where to Log - + +#log_destination = 'stderr' # Valid values are combinations of + # stderr, csvlog, syslog, and eventlog, + # depending on platform. csvlog + # requires logging_collector to be on. + +# This is used when logging to stderr: +#logging_collector = off # Enable capturing of stderr and csvlog + # into log files. Required to be on for + # csvlogs. + # (change requires restart) + +# These are only used if logging_collector is on: +#log_directory = 'log' # directory where log files are written, + # can be absolute or relative to PGDATA +#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern, + # can include strftime() escapes +#log_file_mode = 0600 # creation mode for log files, + # begin with 0 to use octal notation +#log_truncate_on_rotation = off # If on, an existing log file with the + # same name as the new log file will be + # truncated rather than appended to. + # But such truncation only occurs on + # time-driven rotation, not on restarts + # or size-driven rotation. Default is + # off, meaning append to existing files + # in all cases. +#log_rotation_age = 1d # Automatic rotation of logfiles will + # happen after that time. 0 disables. +#log_rotation_size = 10MB # Automatic rotation of logfiles will + # happen after that much log output. + # 0 disables. + +# These are relevant when logging to syslog: +#syslog_facility = 'LOCAL0' +#syslog_ident = 'postgres' +#syslog_sequence_numbers = on +#syslog_split_messages = on + +# This is only relevant when logging to eventlog (win32): +# (change requires restart) +#event_source = 'PostgreSQL' + +# - When to Log - + +#log_min_messages = warning # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic + +#log_min_error_statement = error # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic (effectively off) + +#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements + # and their durations, > 0 logs only + # statements running at least this number + # of milliseconds + +#log_transaction_sample_rate = 0.0 # Fraction of transactions whose statements + # are logged regardless of their duration. 1.0 logs all + # statements from all transactions, 0.0 never logs. + +# - What to Log - + +#debug_print_parse = off +#debug_print_rewritten = off +#debug_print_plan = off +#debug_pretty_print = on +#log_checkpoints = off +#log_connections = off +#log_disconnections = off +#log_duration = off +#log_error_verbosity = default # terse, default, or verbose messages +#log_hostname = off +#log_line_prefix = '%m [%p] ' # special values: + # %a = application name + # %u = user name + # %d = database name + # %r = remote host and port + # %h = remote host + # %p = process ID + # %t = timestamp without milliseconds + # %m = timestamp with milliseconds + # %n = timestamp with milliseconds (as a Unix epoch) + # %i = command tag + # %e = SQL state + # %c = session ID + # %l = session line number + # %s = session start timestamp + # %v = virtual transaction ID + # %x = transaction ID (0 if none) + # %q = stop here in non-session + # processes + # %% = '%' + # e.g. '<%u%%%d> ' +#log_lock_waits = off # log lock waits >= deadlock_timeout +#log_statement = 'none' # none, ddl, mod, all +#log_replication_commands = off +#log_temp_files = -1 # log temporary files equal or larger + # than the specified size in kilobytes; + # -1 disables, 0 logs all temp files +#log_timezone = 'GMT' + +#------------------------------------------------------------------------------ +# PROCESS TITLE +#------------------------------------------------------------------------------ + +#cluster_name = '' # added to process titles if nonempty + # (change requires restart) +#update_process_title = on + + +#------------------------------------------------------------------------------ +# STATISTICS +#------------------------------------------------------------------------------ + +# - Query and Index Statistics Collector - + +#track_activities = on +#track_counts = on +#track_io_timing = off +#track_functions = none # none, pl, all +#track_activity_query_size = 1024 # (change requires restart) +#stats_temp_directory = 'pg_stat_tmp' + + +# - Monitoring - + +#log_parser_stats = off +#log_planner_stats = off +#log_executor_stats = off +#log_statement_stats = off + + +#------------------------------------------------------------------------------ +# AUTOVACUUM +#------------------------------------------------------------------------------ + +#autovacuum = on # Enable autovacuum subprocess? 'on' + # requires track_counts to also be on. +#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and + # their durations, > 0 logs only + # actions running at least this number + # of milliseconds. +#autovacuum_max_workers = 3 # max number of autovacuum subprocesses + # (change requires restart) +#autovacuum_naptime = 1min # time between autovacuum runs +#autovacuum_vacuum_threshold = 50 # min number of row updates before + # vacuum +#autovacuum_analyze_threshold = 50 # min number of row updates before + # analyze +#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum +#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze +#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum + # (change requires restart) +#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age + # before forced vacuum + # (change requires restart) +#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for + # autovacuum, in milliseconds; + # -1 means use vacuum_cost_delay +#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for + # autovacuum, -1 means use + # vacuum_cost_limit + + +#------------------------------------------------------------------------------ +# CLIENT CONNECTION DEFAULTS +#------------------------------------------------------------------------------ + +# - Statement Behavior - + +#client_min_messages = notice # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # log + # notice + # warning + # error +#search_path = '"$user", public' # schema names +#row_security = on +#default_tablespace = '' # a tablespace name, '' uses the default +#temp_tablespaces = '' # a list of tablespace names, '' uses + # only default tablespace +#default_table_access_method = 'heap' +#check_function_bodies = on +#default_transaction_isolation = 'read committed' +#default_transaction_read_only = off +#default_transaction_deferrable = off +#session_replication_role = 'origin' +#statement_timeout = 0 # in milliseconds, 0 is disabled +#lock_timeout = 0 # in milliseconds, 0 is disabled +#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled +#vacuum_freeze_min_age = 50000000 +#vacuum_freeze_table_age = 150000000 +#vacuum_multixact_freeze_min_age = 5000000 +#vacuum_multixact_freeze_table_age = 150000000 +#vacuum_cleanup_index_scale_factor = 0.1 # fraction of total number of tuples + # before index cleanup, 0 always performs + # index cleanup +#bytea_output = 'hex' # hex, escape +#xmlbinary = 'base64' +#xmloption = 'content' +#gin_fuzzy_search_limit = 0 +#gin_pending_list_limit = 4MB + +# - Locale and Formatting - + +#datestyle = 'iso, mdy' +#intervalstyle = 'postgres' +#timezone = 'GMT' +#timezone_abbreviations = 'Default' # Select the set of available time zone + # abbreviations. Currently, there are + # Default + # Australia (historical usage) + # India + # You can create your own file in + # share/timezonesets/. +#extra_float_digits = 1 # min -15, max 3; any value >0 actually + # selects precise output mode +#client_encoding = sql_ascii # actually, defaults to database + # encoding + +# These settings are initialized by initdb, but they can be changed. +#lc_messages = 'C' # locale for system error message + # strings +#lc_monetary = 'C' # locale for monetary formatting +#lc_numeric = 'C' # locale for number formatting +#lc_time = 'C' # locale for time formatting + +# default configuration for text search +#default_text_search_config = 'pg_catalog.simple' + +# - Shared Library Preloading - + +#shared_preload_libraries = '' # (change requires restart) +#local_preload_libraries = '' +#session_preload_libraries = '' +#jit_provider = 'llvmjit' # JIT library to use + +# - Other Defaults - + +#dynamic_library_path = '$libdir' + + +#------------------------------------------------------------------------------ +# LOCK MANAGEMENT +#------------------------------------------------------------------------------ + +#deadlock_timeout = 1s +#max_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_relation = -2 # negative values mean + # (max_pred_locks_per_transaction + # / -max_pred_locks_per_relation) - 1 +#max_pred_locks_per_page = 2 # min 0 + + +#------------------------------------------------------------------------------ +# VERSION AND PLATFORM COMPATIBILITY +#------------------------------------------------------------------------------ + +# - Previous PostgreSQL Versions - + +#array_nulls = on +#backslash_quote = safe_encoding # on, off, or safe_encoding +#escape_string_warning = on +#lo_compat_privileges = off +#operator_precedence_warning = off +#quote_all_identifiers = off +#standard_conforming_strings = on +#synchronize_seqscans = on + +# - Other Platforms and Clients - + +#transform_null_equals = off + + +#------------------------------------------------------------------------------ +# ERROR HANDLING +#------------------------------------------------------------------------------ + +#exit_on_error = off # terminate session on any error? +#restart_after_crash = on # reinitialize after backend crash? +#data_sync_retry = off # retry or panic on failure to fsync + # data? + # (change requires restart) + + +#------------------------------------------------------------------------------ +# CONFIG FILE INCLUDES +#------------------------------------------------------------------------------ + +# These options allow settings to be loaded from files other than the +# default postgresql.conf. Note that these are directives, not variable +# assignments, so they can usefully be given more than once. + +#include_dir = '...' # include files ending in '.conf' from + # a directory, e.g., 'conf.d' +#include_if_exists = '...' # include file only if it exists +#include = '...' # include file + + +#------------------------------------------------------------------------------ +# CUSTOMIZED OPTIONS +#------------------------------------------------------------------------------ + +# Add settings for extensions here diff --git a/molecule/quarkus_ha/prepare.yml b/molecule/quarkus_ha/prepare.yml new file mode 100644 index 0000000..dff1821 --- /dev/null +++ b/molecule/quarkus_ha/prepare.yml @@ -0,0 +1,44 @@ +--- +- name: Prepare + hosts: keycloak + tasks: + - name: "Display hera_home if defined." + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - name: "Ensure common prepare phase are set." + ansible.builtin.include_tasks: ../prepare.yml + + - name: Create certificate request + ansible.builtin.command: "openssl req -x509 -newkey rsa:4096 -keyout {{ inventory_hostname }}.key -out {{ inventory_hostname }}.pem -sha256 -days 365 -nodes -subj '/CN={{ inventory_hostname }}'" + delegate_to: localhost + changed_when: False + + - name: Create vault directory + become: true + ansible.builtin.file: + state: directory + path: "/opt/keycloak/vault" + mode: 0755 + + - name: Make sure a jre is available (for keytool to prepare keystore) + delegate_to: localhost + ansible.builtin.package: + name: "{{ 'java-17-openjdk-headless' if hera_home | length > 0 else 'openjdk-17-jdk-headless' }}" + state: present + become: true + failed_when: false + + - name: Create vault keystore + ansible.builtin.command: keytool -importpass -alias TestRealm_testalias -keystore keystore.p12 -storepass keystorepassword + delegate_to: localhost + register: keytool_cmd + changed_when: False + failed_when: not 'already exists' in keytool_cmd.stdout and keytool_cmd.rc != 0 + + - name: Copy certificates and vault + become: true + ansible.builtin.copy: + src: keystore.p12 + dest: /opt/keycloak/vault/keystore.p12 + mode: 0444 diff --git a/molecule/quarkus_ha/roles b/molecule/quarkus_ha/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/quarkus_ha/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/molecule/quarkus_ha/verify.yml b/molecule/quarkus_ha/verify.yml new file mode 100644 index 0000000..dd8490f --- /dev/null +++ b/molecule/quarkus_ha/verify.yml @@ -0,0 +1,86 @@ +--- +- name: Verify + hosts: all + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + + - name: Check if keycloak service started + ansible.builtin.assert: + that: + - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" + fail_msg: "Service not running" + + - name: Set internal envvar + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - name: Verify openid config + when: + - hera_home is defined + - hera_home | length == 0 + block: + - name: Fetch openID config # noqa blocked_modules command-instead-of-module + ansible.builtin.shell: | + set -o pipefail + curl -H 'Host: instance' https://localhost:8443/realms/master/.well-known/openid-configuration -k | jq . + args: + executable: /bin/bash + delegate_to: localhost + register: openid_config + changed_when: False + - name: Verify endpoint URLs + ansible.builtin.assert: + that: + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://instance/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'https://instance/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/token' + delegate_to: localhost + + - name: Check log folder + ansible.builtin.stat: + path: /tmp/keycloak + register: keycloak_log_folder + + - name: Check that keycloak log folder exists and is a link + ansible.builtin.assert: + that: + - keycloak_log_folder.stat.exists + - not keycloak_log_folder.stat.isdir + - keycloak_log_folder.stat.islnk + fail_msg: "Service log symlink not correctly created" + + - name: Check log file + become: true + ansible.builtin.stat: + path: /tmp/keycloak/keycloak.log + register: keycloak_log_file + + - name: Check if keycloak file exists + ansible.builtin.assert: + that: + - keycloak_log_file.stat.exists + - not keycloak_log_file.stat.isdir + + - name: Check default log folder + become: yes + ansible.builtin.stat: + path: /var/log/keycloak + register: keycloak_default_log_folder + failed_when: false + + - name: Check that default keycloak log folder doesn't exist + ansible.builtin.assert: + that: + - not keycloak_default_log_folder.stat.exists + + - name: Verify vault SPI in logfile + become: true + ansible.builtin.shell: | + set -o pipefail + zgrep 'Configured KeystoreVaultProviderFactory with the keystore file' /opt/keycloak/keycloak-*/data/log/keycloak.log*zip + changed_when: false + failed_when: slurped_log.rc != 0 + register: slurped_log diff --git a/roles/keycloak_quarkus/tasks/restart/serial.yml b/roles/keycloak_quarkus/tasks/restart/serial.yml index d98dbf9..26397d3 100644 --- a/roles/keycloak_quarkus/tasks/restart/serial.yml +++ b/roles/keycloak_quarkus/tasks/restart/serial.yml @@ -1,11 +1,11 @@ --- - name: "Restart services in serial, with optional healtch check (keycloak_quarkus_restart_health_check)" throttle: 1 - loop: "{{ ansible_play_hosts }}" block: - name: "Restart and enable {{ keycloak.service_name }} service on {{ item }}" ansible.builtin.include_tasks: - file: ../restart.yml + file: restart.yml apply: delegate_to: "{{ item }}" run_once: true + loop: "{{ ansible_play_hosts }}" diff --git a/roles/keycloak_quarkus/templates/quarkus.properties.j2 b/roles/keycloak_quarkus/templates/quarkus.properties.j2 index 5689bfc..93152e8 100644 --- a/roles/keycloak_quarkus/templates/quarkus.properties.j2 +++ b/roles/keycloak_quarkus/templates/quarkus.properties.j2 @@ -1,6 +1,6 @@ {{ ansible_managed | comment }} {% if keycloak_quarkus_ha_enabled %} -{% if not rhbk_enable or keycloak_quarkus_version.split('.')[0]|int < 22 %} +{% if keycloak_quarkus_version.split('.')[0] | int < 22 %} quarkus.infinispan-client.server-list={{ keycloak_quarkus_ispn_hosts }} quarkus.infinispan-client.auth-username={{ keycloak_quarkus_ispn_user }} quarkus.infinispan-client.auth-password={{ keycloak_quarkus_ispn_pass }} From f63b20b9d40a22bafdad0ec996789e7e951b672d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 15 May 2024 20:01:58 +0200 Subject: [PATCH 277/376] Update verify steps --- molecule/quarkus/converge.yml | 2 +- molecule/quarkus_ha/verify.yml | 61 ++-------------------------------- 2 files changed, 3 insertions(+), 60 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index da0f3dc..b7430a1 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -7,7 +7,7 @@ keycloak_realm: TestRealm keycloak_quarkus_host: instance keycloak_quarkus_log: file - keycloak_quarkus_log_level: info + keycloak_quarkus_log_level: debug # needed for the verify step keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_key_file_copy_enabled: true keycloak_quarkus_key_content: "{{ lookup('file', 'key.pem') }}" diff --git a/molecule/quarkus_ha/verify.yml b/molecule/quarkus_ha/verify.yml index dd8490f..c1a2fb9 100644 --- a/molecule/quarkus_ha/verify.yml +++ b/molecule/quarkus_ha/verify.yml @@ -1,6 +1,6 @@ --- - name: Verify - hosts: all + hosts: keycloak tasks: - name: Populate service facts ansible.builtin.service_facts: @@ -16,46 +16,10 @@ ansible.builtin.set_fact: hera_home: "{{ lookup('env', 'HERA_HOME') }}" - - name: Verify openid config - when: - - hera_home is defined - - hera_home | length == 0 - block: - - name: Fetch openID config # noqa blocked_modules command-instead-of-module - ansible.builtin.shell: | - set -o pipefail - curl -H 'Host: instance' https://localhost:8443/realms/master/.well-known/openid-configuration -k | jq . - args: - executable: /bin/bash - delegate_to: localhost - register: openid_config - changed_when: False - - name: Verify endpoint URLs - ansible.builtin.assert: - that: - - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://instance/realms/master/protocol/openid-connect/ext/ciba/auth' - - (openid_config.stdout | from_json)['issuer'] == 'https://instance/realms/master' - - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/auth' - - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/token' - delegate_to: localhost - - - name: Check log folder - ansible.builtin.stat: - path: /tmp/keycloak - register: keycloak_log_folder - - - name: Check that keycloak log folder exists and is a link - ansible.builtin.assert: - that: - - keycloak_log_folder.stat.exists - - not keycloak_log_folder.stat.isdir - - keycloak_log_folder.stat.islnk - fail_msg: "Service log symlink not correctly created" - - name: Check log file become: true ansible.builtin.stat: - path: /tmp/keycloak/keycloak.log + path: /var/log/keycloak/keycloak.log register: keycloak_log_file - name: Check if keycloak file exists @@ -63,24 +27,3 @@ that: - keycloak_log_file.stat.exists - not keycloak_log_file.stat.isdir - - - name: Check default log folder - become: yes - ansible.builtin.stat: - path: /var/log/keycloak - register: keycloak_default_log_folder - failed_when: false - - - name: Check that default keycloak log folder doesn't exist - ansible.builtin.assert: - that: - - not keycloak_default_log_folder.stat.exists - - - name: Verify vault SPI in logfile - become: true - ansible.builtin.shell: | - set -o pipefail - zgrep 'Configured KeystoreVaultProviderFactory with the keystore file' /opt/keycloak/keycloak-*/data/log/keycloak.log*zip - changed_when: false - failed_when: slurped_log.rc != 0 - register: slurped_log From 4b21569f3635526f6e5330e7203187d520b93e17 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 16 May 2024 11:16:20 +0200 Subject: [PATCH 278/376] parameterize health check; refactor serial_then_parallel --- roles/keycloak_quarkus/README.md | 2 ++ roles/keycloak_quarkus/defaults/main.yml | 2 ++ .../keycloak_quarkus/meta/argument_specs.yml | 8 +++++ roles/keycloak_quarkus/tasks/restart.yml | 6 ++-- .../tasks/restart/serial_then_parallel.yml | 33 +++++-------------- 5 files changed, 23 insertions(+), 28 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index a9dbea0..ce94392 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -103,6 +103,8 @@ Role Defaults |`keycloak_quarkus_systemd_wait_for_delay`| Activation delay for service systemd unit (seconds) | `10` | |`keycloak_quarkus_restart_strategy`| Strategy task file for restarting in HA (one of provided restart/['serial.yml','none.yml','serial_then_parallel.yml']) or path to file when providing custom strategy | `restart/serial.yml` | |`keycloak_quarkus_restart_health_check`| Whether to wait for successful health check after restart | `{{ keycloak_quarkus_ha_enabled }}` | +|`keycloak_quarkus_restart_health_check_delay`| Seconds to let pass before starting healch checks | `10` | +|`keycloak_quarkus_restart_health_check_reries`| Number of attempts for successful health check before failing | `25` | |`keycloak_quarkus_restart_pause`| Seconds to wait between restarts in HA strategy | `15` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index c152a20..46aca81 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -157,4 +157,6 @@ keycloak_quarkus_supported_policy_types: ['password-blacklists'] # files in restart directory (one of [ 'serial', 'none', 'serial_then_parallel' ]), or path to file when providing custom strategy keycloak_quarkus_restart_strategy: restart/serial.yml keycloak_quarkus_restart_health_check: "{{ keycloak_quarkus_ha_enabled }}" +keycloak_quarkus_restart_health_check_delay: 10 +keycloak_quarkus_restart_health_check_reries: 25 keycloak_quarkus_restart_pause: 15 diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 3e06525..57eea53 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -445,6 +445,14 @@ argument_specs: description: "Seconds to wait between restarts in HA strategy" default: 15 type: int + keycloak_quarkus_restart_health_check_delay: + description: "Seconds to let pass before starting healch checks" + default: 10 + type: 'int' + keycloak_quarkus_restart_health_check_reries: + description: "Number of attempts for successful health check before failing" + default: 25 + type: 'int' downstream: options: rhbk_version: diff --git a/roles/keycloak_quarkus/tasks/restart.yml b/roles/keycloak_quarkus/tasks/restart.yml index bcb8c1d..2a1fabd 100644 --- a/roles/keycloak_quarkus/tasks/restart.yml +++ b/roles/keycloak_quarkus/tasks/restart.yml @@ -12,9 +12,9 @@ url: "{{ keycloak.health_url }}" register: keycloak_status until: keycloak_status.status == 200 - retries: 25 - delay: 10 - when: keycloak_quarkus_restart_health_check + retries: "{{ keycloak_quarkus_restart_health_check_reries }}" + delay: "{{ keycloak_quarkus_restart_health_check_delay }}" + when: internal_force_health_check | default(keycloak_quarkus_restart_health_check) - name: Pause to give distributed ispn caches time to (re-)replicate back onto first host ansible.builtin.pause: diff --git a/roles/keycloak_quarkus/tasks/restart/serial_then_parallel.yml b/roles/keycloak_quarkus/tasks/restart/serial_then_parallel.yml index 372a302..d883ff1 100644 --- a/roles/keycloak_quarkus/tasks/restart/serial_then_parallel.yml +++ b/roles/keycloak_quarkus/tasks/restart/serial_then_parallel.yml @@ -1,31 +1,14 @@ --- - name: Verify first restarted service with health URL, then rest restart in parallel block: - - name: "Restart and enable {{ keycloak.service_name }} service on first host" - ansible.builtin.systemd: - name: "{{ keycloak.service_name }}" - enabled: true - state: restarted - daemon_reload: true - become: true - delegate_to: "{{ ansible_play_hosts | first }}" - run_once: true - - - name: "Wait until {{ keycloak.service_name }} service becomes active {{ keycloak.health_url }}" - ansible.builtin.uri: - url: "{{ keycloak.health_url }}" - register: keycloak_status - until: keycloak_status.status == 200 - retries: 25 - delay: 10 - delegate_to: "{{ ansible_play_hosts | first }}" - run_once: true - - - name: Pause to give distributed ispn caches time to (re-)replicate back onto first host - ansible.builtin.pause: - seconds: "{{ keycloak_quarkus_restart_pause }}" - when: - - keycloak_quarkus_ha_enabled + - name: "Restart and enable {{ keycloak.service_name }} service on initial host" + ansible.builtin.include_tasks: + file: restart.yml + apply: + delegate_to: "{{ ansible_play_hosts | first }}" + run_once: true + vars: + internal_force_health_check: true - name: "Restart and enable {{ keycloak.service_name }} service on other hosts" ansible.builtin.systemd: From 6f2ed4d53b9a20f5e613556bbb2136314cea6ebe Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 14 May 2024 10:41:46 +0200 Subject: [PATCH 279/376] Fix #226 - minor proxy-header enhancement --- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index f55ee80..6291b38 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -69,13 +69,12 @@ cache-config-file=cache-ispn.xml {% endif %} {% endif %} -{% if keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %} -# Deprecated Proxy configuration -proxy={{ keycloak_quarkus_proxy_mode }} -{% endif %} {% if keycloak_quarkus_proxy_headers is defined and keycloak_quarkus_proxy_headers != "none" %} # Proxy proxy-headers={{ keycloak_quarkus_proxy_headers }} +{% elif keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %} +# Deprecated Proxy configuration +proxy={{ keycloak_quarkus_proxy_mode }} {% endif %} spi-sticky-session-encoder-infinispan-should-attach-route={{ keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route | d(true) | lower }} From 0fd8eb52d2920e16a3db9c229b32b358b775020b Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 14 May 2024 20:05:14 +0200 Subject: [PATCH 280/376] #226: CR changes --- roles/keycloak_quarkus/tasks/prereqs.yml | 7 +++++++ roles/keycloak_quarkus/templates/keycloak.conf.j2 | 5 ++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 220f65b..503b308 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -93,3 +93,10 @@ fail_msg: "Additional env variable definition is incorrect: `key` and `value` are mandatory." no_log: true loop: "{{ keycloak_quarkus_additional_env_vars }}" + +- name: "Validate proxy-headers" + ansible.builtin.assert: + that: + - keycloak_quarkus_proxy_headers | lower in ['', 'forwarded', 'xforwarded'] + quiet: true + fail_msg: "keycloak_quarkus_proxy_headers must be either '', 'forwarded' or 'xforwarded'" diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 6291b38..ab4024b 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -69,9 +69,8 @@ cache-config-file=cache-ispn.xml {% endif %} {% endif %} -{% if keycloak_quarkus_proxy_headers is defined and keycloak_quarkus_proxy_headers != "none" %} -# Proxy -proxy-headers={{ keycloak_quarkus_proxy_headers }} +{% if keycloak_quarkus_proxy_headers | length > 0 %} +proxy-headers={{ keycloak_quarkus_proxy_headers | lower }} {% elif keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %} # Deprecated Proxy configuration proxy={{ keycloak_quarkus_proxy_mode }} From 4d31117c16555c3ac6f46f0911d6ad7c85dfdec0 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 14 May 2024 20:15:51 +0200 Subject: [PATCH 281/376] Fix RHBK version --- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 57eea53..66cae79 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -456,7 +456,7 @@ argument_specs: downstream: options: rhbk_version: - default: "24.0.4" + default: "24.0.3" description: "Red Hat Build of Keycloak version" type: "str" rhbk_archive: From cc012767a4416a5348cea2038661dc4bb42feb38 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 14 May 2024 20:16:00 +0200 Subject: [PATCH 282/376] #226 - add deprecation warning --- roles/keycloak_quarkus/tasks/deprecations.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/roles/keycloak_quarkus/tasks/deprecations.yml b/roles/keycloak_quarkus/tasks/deprecations.yml index a81c808..556879a 100644 --- a/roles/keycloak_quarkus/tasks/deprecations.yml +++ b/roles/keycloak_quarkus/tasks/deprecations.yml @@ -34,3 +34,20 @@ - name: Flush handlers ansible.builtin.meta: flush_handlers + +# https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/24.0/html-single/upgrading_guide/index#deprecated_literal_proxy_literal_option +- name: Check deprecation of keycloak_quarkus_proxy_mode + delegate_to: localhost + run_once: true + when: + - keycloak_quarkus_proxy_mode is defined + - keycloak_quarkus_proxy_headers is defined and keycloak_quarkus_proxy_headers | length == 0 + - keycloak_quarkus_version.split('.') | first | int >= 24 + changed_when: true + ansible.builtin.set_fact: + deprecated_variable: "keycloak_quarkus_proxy_mode" # read in deprecation handler + notify: + - print deprecation warning + +- name: Flush handlers + ansible.builtin.meta: flush_handlers From 92c24e49e7f1a1ad7e1683bb1ea3e8ac1741dbf5 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Wed, 15 May 2024 11:09:58 +0200 Subject: [PATCH 283/376] #226: add proper default value for proxy-headers --- roles/keycloak_quarkus/defaults/main.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 46aca81..a0f6fa4 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -91,7 +91,10 @@ keycloak_quarkus_hostname_strict: true # If all applications use the public URL this option should be enabled. keycloak_quarkus_hostname_strict_backchannel: false -# proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] +# The proxy headers that should be accepted by the server. ['', 'forwarded', 'xforwarded'] +keycloak_quarkus_proxy_headers: "" + +# deprecated: proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough] keycloak_quarkus_proxy_mode: edge # disable xa transactions From 62cbaa35966f7edfeeeb4f76497a4b87de840f7e Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Thu, 16 May 2024 16:24:25 +0200 Subject: [PATCH 284/376] Introduce keycloak_quarkus_show_deprecation_warnings, disabled in molecule tests --- molecule/debian/converge.yml | 1 + molecule/https_revproxy/converge.yml | 3 ++- molecule/quarkus-devmode/converge.yml | 3 ++- molecule/quarkus/converge.yml | 1 + molecule/quarkus_ha/converge.yml | 1 + molecule/quarkus_upgrade/converge.yml | 1 + roles/keycloak_quarkus/README.md | 1 + roles/keycloak_quarkus/defaults/main.yml | 2 ++ roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/tasks/deprecations.yml | 10 +++++----- 10 files changed, 20 insertions(+), 7 deletions(-) diff --git a/molecule/debian/converge.yml b/molecule/debian/converge.yml index 17517b8..e6319b7 100644 --- a/molecule/debian/converge.yml +++ b/molecule/debian/converge.yml @@ -2,6 +2,7 @@ - name: Converge hosts: all vars: + keycloak_quarkus_show_deprecation_warnings: false keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_realm: TestRealm keycloak_quarkus_log: file diff --git a/molecule/https_revproxy/converge.yml b/molecule/https_revproxy/converge.yml index b1eb7bc..b490721 100644 --- a/molecule/https_revproxy/converge.yml +++ b/molecule/https_revproxy/converge.yml @@ -1,7 +1,8 @@ --- - name: Converge hosts: all - vars: + vars: + keycloak_quarkus_show_deprecation_warnings: false keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_admin_password: "remembertochangeme" keycloak_realm: TestRealm diff --git a/molecule/quarkus-devmode/converge.yml b/molecule/quarkus-devmode/converge.yml index 2a45189..2e5d351 100644 --- a/molecule/quarkus-devmode/converge.yml +++ b/molecule/quarkus-devmode/converge.yml @@ -1,7 +1,8 @@ --- - name: Converge hosts: all - vars: + vars: + keycloak_quarkus_show_deprecation_warnings: false keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_admin_password: "remembertochangeme" keycloak_realm: TestRealm diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index b7430a1..7c86756 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -2,6 +2,7 @@ - name: Converge hosts: all vars: + keycloak_quarkus_show_deprecation_warnings: false keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_admin_password: "remembertochangeme" keycloak_realm: TestRealm diff --git a/molecule/quarkus_ha/converge.yml b/molecule/quarkus_ha/converge.yml index 2434e65..00246b8 100644 --- a/molecule/quarkus_ha/converge.yml +++ b/molecule/quarkus_ha/converge.yml @@ -2,6 +2,7 @@ - name: Converge hosts: keycloak vars: + keycloak_quarkus_show_deprecation_warnings: false keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_admin_password: "remembertochangeme" keycloak_realm: TestRealm diff --git a/molecule/quarkus_upgrade/converge.yml b/molecule/quarkus_upgrade/converge.yml index eb84589..6025b7c 100644 --- a/molecule/quarkus_upgrade/converge.yml +++ b/molecule/quarkus_upgrade/converge.yml @@ -4,6 +4,7 @@ vars_files: - vars.yml vars: + keycloak_quarkus_show_deprecation_warnings: false keycloak_quarkus_version: 24.0.3 roles: - role: keycloak_quarkus diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index ce94392..a20c760 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -167,6 +167,7 @@ Role Defaults |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | |`keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route`| If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy | `True` | +|`keycloak_quarkus_show_deprecation_warnings`| Whether deprecation warnings should be shown | `True` | #### Vault SPI diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index a0f6fa4..b3752c5 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -8,6 +8,8 @@ keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_q # whether to install from local archive keycloak_quarkus_offline_install: false +keycloak_quarkus_show_deprecation_warnings: true + ### Install location and service settings keycloak_quarkus_java_home: keycloak_quarkus_dest: /opt/keycloak diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 66cae79..659e7f6 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -483,6 +483,10 @@ argument_specs: default: false description: "Perform an offline install" type: "bool" + keycloak_quarkus_show_deprecation_warnings: + default: true + description: "Whether deprecation warnings should be shown" + type: "bool" rhbk_service_name: default: "rhbk" description: "systemd service name for Red Hat Build of Keycloak" diff --git a/roles/keycloak_quarkus/tasks/deprecations.yml b/roles/keycloak_quarkus/tasks/deprecations.yml index 556879a..27ea6e3 100644 --- a/roles/keycloak_quarkus/tasks/deprecations.yml +++ b/roles/keycloak_quarkus/tasks/deprecations.yml @@ -10,7 +10,7 @@ - keycloak_quarkus_key_store_file is defined - keycloak_quarkus_key_store_file != '' - keycloak_quarkus_https_key_store_file == keycloak.home + "/conf/key_store.p12" # default value - changed_when: true + changed_when: keycloak_quarkus_show_deprecation_warnings ansible.builtin.set_fact: keycloak_quarkus_https_key_store_file: "{{ keycloak_quarkus_key_store_file }}" deprecated_variable: "keycloak_quarkus_key_store_file" # read in deprecation handler @@ -25,7 +25,7 @@ - keycloak_quarkus_key_store_password is defined - keycloak_quarkus_key_store_password != '' - keycloak_quarkus_https_key_store_password == "" # default value - changed_when: true + changed_when: keycloak_quarkus_show_deprecation_warnings ansible.builtin.set_fact: keycloak_quarkus_https_key_store_password: "{{ keycloak_quarkus_key_store_password }}" deprecated_variable: "keycloak_quarkus_key_store_password" # read in deprecation handler @@ -37,13 +37,13 @@ # https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/24.0/html-single/upgrading_guide/index#deprecated_literal_proxy_literal_option - name: Check deprecation of keycloak_quarkus_proxy_mode - delegate_to: localhost - run_once: true when: - keycloak_quarkus_proxy_mode is defined - keycloak_quarkus_proxy_headers is defined and keycloak_quarkus_proxy_headers | length == 0 - keycloak_quarkus_version.split('.') | first | int >= 24 - changed_when: true + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings ansible.builtin.set_fact: deprecated_variable: "keycloak_quarkus_proxy_mode" # read in deprecation handler notify: From df1939e387f6028b88faee6227be6a87d27c8ce6 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Mon, 20 May 2024 10:21:55 +0000 Subject: [PATCH 285/376] Update changelog for release 2.3.0 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 23 +++++++++++++++++++++++ changelogs/changelog.yaml | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3d0f005..f139898 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,29 @@ middleware\_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.3.0 +====== + +Major Changes +------------- + +- Allow for custom providers hosted on maven repositories `#223 `_ +- Restart handler strategy behaviour `#231 `_ + +Minor Changes +------------- + +- Add support for policy files `#225 `_ +- Allow to add extra custom env vars in sysconfig file `#229 `_ +- Download from alternate URL with optional http authentication `#220 `_ +- Update Keycloak to version 24.0.4 `#218 `_ +- ``proxy-header`` enhancement `#227 `_ + +Bugfixes +-------- + +- ``kc.sh build`` uses configured jdk `#211 `_ + v2.2.2 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index fe5c499..773f77d 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -532,3 +532,42 @@ releases: - 209.yaml - 210.yaml release_date: '2024-05-06' + 2.3.0: + changes: + bugfixes: + - '``kc.sh build`` uses configured jdk `#211 `_ + + ' + major_changes: + - 'Allow for custom providers hosted on maven repositories `#223 `_ + + ' + - 'Restart handler strategy behaviour `#231 `_ + + ' + minor_changes: + - 'Add support for policy files `#225 `_ + + ' + - 'Allow to add extra custom env vars in sysconfig file `#229 `_ + + ' + - 'Download from alternate URL with optional http authentication `#220 `_ + + ' + - 'Update Keycloak to version 24.0.4 `#218 `_ + + ' + - '``proxy-header`` enhancement `#227 `_ + + ' + fragments: + - 211.yaml + - 218.yaml + - 220.yaml + - 223.yaml + - 225.yaml + - 227.yaml + - 229.yaml + - 231.yaml + release_date: '2024-05-20' From 8ca73364e98e283e5b798d4381d75967386d77c4 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Mon, 20 May 2024 10:22:09 +0000 Subject: [PATCH 286/376] Bump version to 2.3.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index da8794c..1a4d35a 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.3.0" +version: "2.3.1" readme: README.md authors: - Romain Pelisse From 2092c2d23a2c028149d314205735a8970b713fd8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 21 May 2024 12:27:45 +0200 Subject: [PATCH 287/376] Update minimum ansible-core version > 2.15 --- README.md | 2 +- meta/runtime.yml | 2 +- roles/keycloak/meta/main.yml | 2 +- roles/keycloak_quarkus/meta/main.yml | 2 +- roles/keycloak_realm/meta/main.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0cd3ba0..e71a8f6 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Re ## Ansible version compatibility -This collection has been tested against following Ansible versions: **>=2.14.0**. +This collection has been tested against following Ansible versions: **>=2.15.0**. Plugins and modules within a collection may be tested with only specific Ansible versions. A collection may contain metadata that identifies these versions. diff --git a/meta/runtime.yml b/meta/runtime.yml index ce6befd..1e85b01 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1,2 +1,2 @@ --- -requires_ansible: ">=2.14.0" +requires_ansible: ">=2.15.0" diff --git a/roles/keycloak/meta/main.yml b/roles/keycloak/meta/main.yml index a70e9f1..a27afb8 100644 --- a/roles/keycloak/meta/main.yml +++ b/roles/keycloak/meta/main.yml @@ -12,7 +12,7 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.14" + min_ansible_version: "2.15" platforms: - name: EL diff --git a/roles/keycloak_quarkus/meta/main.yml b/roles/keycloak_quarkus/meta/main.yml index 0f82003..40a487f 100644 --- a/roles/keycloak_quarkus/meta/main.yml +++ b/roles/keycloak_quarkus/meta/main.yml @@ -8,7 +8,7 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.14" + min_ansible_version: "2.15" platforms: - name: EL diff --git a/roles/keycloak_realm/meta/main.yml b/roles/keycloak_realm/meta/main.yml index 915f62c..ab861ed 100644 --- a/roles/keycloak_realm/meta/main.yml +++ b/roles/keycloak_realm/meta/main.yml @@ -8,7 +8,7 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.14" + min_ansible_version: "2.15" platforms: - name: EL From ef53ca545af031cb662cb143caf9e288e7fafbb7 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 21 May 2024 12:31:40 +0200 Subject: [PATCH 288/376] update yamllint --- .yamllint | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.yamllint b/.yamllint index fa1f1fc..10e554e 100644 --- a/.yamllint +++ b/.yamllint @@ -15,7 +15,8 @@ rules: commas: max-spaces-after: -1 level: error - comments: disable + comments: + min-spaces-from-content: 1 comments-indentation: disable document-start: disable empty-lines: @@ -30,4 +31,8 @@ rules: new-lines: type: unix trailing-spaces: disable - truthy: disable \ No newline at end of file + truthy: disable + octal-values: + forbid-implicit-octal: true + forbid-explicit-octal: true + From adfee5f6e1e4767fe6fbf70d3431322409491798 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 21 May 2024 12:34:11 +0200 Subject: [PATCH 289/376] ci --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0927320..3d71b46 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,7 @@ on: branches: - main pull_request: + workflow_dispatch: schedule: - cron: '15 6 * * *' From bf1871182b3ce806991278a1efbc99d1e72b387a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 21 May 2024 12:35:33 +0200 Subject: [PATCH 290/376] linter --- roles/keycloak/tasks/fastpackages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak/tasks/fastpackages.yml b/roles/keycloak/tasks/fastpackages.yml index be34c72..a89f7f6 100644 --- a/roles/keycloak/tasks/fastpackages.yml +++ b/roles/keycloak/tasks/fastpackages.yml @@ -14,7 +14,7 @@ - name: "Install packages: {{ packages_to_install }}" become: true - ansible.builtin.yum: + ansible.builtin.dnf: name: "{{ packages_to_install }}" state: present when: From e69e5b7ba4086d5ad0dda3529e2f239669e76392 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 21 May 2024 12:41:31 +0200 Subject: [PATCH 291/376] readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e71a8f6..c5ee5cf 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ ansible-playbook -i -e @rhn-creds.yml playbooks/keycloak.yml -e localhost ansible_connection=local ``` -Note: when deploying clustered configurations, all hosts belonging to the cluster must be present in ansible_play_batch; ie. they must be targeted by the same ansible-playbook execution. +Note: when deploying clustered configurations, all hosts belonging to the cluster must be present in `ansible_play_batch`; ie. they must be targeted by the same ansible-playbook execution. ## Configuration From 4fb44091d6504a669592ce22ea23ebbedeeefa10 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 30 May 2024 08:44:04 +0200 Subject: [PATCH 292/376] ci: fix missing symlink --- molecule/quarkus_upgrade/roles | 1 + 1 file changed, 1 insertion(+) create mode 120000 molecule/quarkus_upgrade/roles diff --git a/molecule/quarkus_upgrade/roles b/molecule/quarkus_upgrade/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/quarkus_upgrade/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file From a4deaa005a374fc599eae658740fd4ff4120c3fe Mon Sep 17 00:00:00 2001 From: Giovanni Toraldo Date: Tue, 4 Jun 2024 17:00:11 +0200 Subject: [PATCH 293/376] Enable by default health check on restart --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index a20c760..a166725 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -102,7 +102,7 @@ Role Defaults |`keycloak_quarkus_systemd_wait_for_timeout`| How long to wait for service to be alive (seconds) | `60` | |`keycloak_quarkus_systemd_wait_for_delay`| Activation delay for service systemd unit (seconds) | `10` | |`keycloak_quarkus_restart_strategy`| Strategy task file for restarting in HA (one of provided restart/['serial.yml','none.yml','serial_then_parallel.yml']) or path to file when providing custom strategy | `restart/serial.yml` | -|`keycloak_quarkus_restart_health_check`| Whether to wait for successful health check after restart | `{{ keycloak_quarkus_ha_enabled }}` | +|`keycloak_quarkus_restart_health_check`| Whether to wait for successful health check after restart | `true` | |`keycloak_quarkus_restart_health_check_delay`| Seconds to let pass before starting healch checks | `10` | |`keycloak_quarkus_restart_health_check_reries`| Number of attempts for successful health check before failing | `25` | |`keycloak_quarkus_restart_pause`| Seconds to wait between restarts in HA strategy | `15` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index b3752c5..4f6deb3 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -161,7 +161,7 @@ keycloak_quarkus_supported_policy_types: ['password-blacklists'] # files in restart directory (one of [ 'serial', 'none', 'serial_then_parallel' ]), or path to file when providing custom strategy keycloak_quarkus_restart_strategy: restart/serial.yml -keycloak_quarkus_restart_health_check: "{{ keycloak_quarkus_ha_enabled }}" +keycloak_quarkus_restart_health_check: true keycloak_quarkus_restart_health_check_delay: 10 keycloak_quarkus_restart_health_check_reries: 25 keycloak_quarkus_restart_pause: 15 diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 659e7f6..978ca7e 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -432,7 +432,7 @@ argument_specs: description: "Allow the option to ignore invalid certificates when downloading JDBC drivers from a custom URL" type: "bool" keycloak_quarkus_restart_health_check: - default: "{{ keycloak_quarkus_ha_enabled }}" + default: true description: "Whether to wait for successful health check after restart" type: "bool" keycloak_quarkus_restart_strategy: From a82bdfbbb6a079e96b013479955b8b5cf612de19 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 4 Jun 2024 17:36:20 +0200 Subject: [PATCH 294/376] Bump to 2.4.0 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 1a4d35a..c64908f 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.3.1" +version: "2.4.0" readme: README.md authors: - Romain Pelisse From e927ddbb6caa3ddd0fba30b9fdd68b6510c5f710 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Tue, 4 Jun 2024 15:44:20 +0000 Subject: [PATCH 295/376] Update changelog for release 2.4.0 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 9 +++++++++ changelogs/changelog.yaml | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f139898..d8fbfdd 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,15 @@ middleware\_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.4.0 +====== + +Major Changes +------------- + +- Enable by default health check on restart `#234 `_ +- Update minimum ansible-core version > 2.15 `#232 `_ + v2.3.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 773f77d..e5de562 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -571,3 +571,16 @@ releases: - 229.yaml - 231.yaml release_date: '2024-05-20' + 2.4.0: + changes: + major_changes: + - 'Enable by default health check on restart `#234 `_ + + ' + - 'Update minimum ansible-core version > 2.15 `#232 `_ + + ' + fragments: + - 232.yaml + - 234.yaml + release_date: '2024-06-04' From 5f059e8d63b8e5e04d957951a4820a4ff90cb901 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Tue, 4 Jun 2024 15:44:35 +0000 Subject: [PATCH 296/376] Bump version to 2.4.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index c64908f..7ff57c6 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.4.0" +version: "2.4.1" readme: README.md authors: - Romain Pelisse From c6fac7bb70932f6ea852483f86deea8a3f9b3d36 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 27 Jun 2024 11:00:29 +0200 Subject: [PATCH 297/376] ci: add traffic wf --- .github/workflows/traffic.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/traffic.yml diff --git a/.github/workflows/traffic.yml b/.github/workflows/traffic.yml new file mode 100644 index 0000000..6b0dde7 --- /dev/null +++ b/.github/workflows/traffic.yml @@ -0,0 +1,24 @@ +on: + schedule: + - cron: "51 23 * * 0" + +jobs: + traffic: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + ref: "traffic" + + - name: GitHub traffic + uses: sangonzal/repository-traffic-action@v.0.1.6 + env: + TRAFFIC_ACTION_TOKEN: ${{ secrets.TRIGGERING_PAT }} + + - name: Commit changes + uses: EndBug/add-and-commit@v4 + with: + author_name: Ansible Middleware + message: "GitHub traffic" + add: "./traffic/*" + ref: "traffic" From 64e2a95685459155f1b2fcb3a9314ba1c9bf245b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 27 Jun 2024 11:01:38 +0200 Subject: [PATCH 298/376] ci: add traffic wf --- .github/workflows/traffic.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/traffic.yml b/.github/workflows/traffic.yml index 6b0dde7..1d85eac 100644 --- a/.github/workflows/traffic.yml +++ b/.github/workflows/traffic.yml @@ -1,6 +1,8 @@ +name: Collect traffic stats on: schedule: - cron: "51 23 * * 0" + workflow_dispatch: jobs: traffic: From e40f5549367e124103863db08d18f8edb389854d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 27 Jun 2024 11:02:32 +0200 Subject: [PATCH 299/376] ci: add traffic wf --- .github/workflows/traffic.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/traffic.yml b/.github/workflows/traffic.yml index 1d85eac..b4f245e 100644 --- a/.github/workflows/traffic.yml +++ b/.github/workflows/traffic.yml @@ -10,7 +10,7 @@ jobs: steps: - uses: actions/checkout@v2 with: - ref: "traffic" + ref: "gh-pages" - name: GitHub traffic uses: sangonzal/repository-traffic-action@v.0.1.6 @@ -23,4 +23,4 @@ jobs: author_name: Ansible Middleware message: "GitHub traffic" add: "./traffic/*" - ref: "traffic" + ref: "gh-pages" From 94f1b8b35589edd75667188115afec8a35b2c787 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 2 Jul 2024 15:46:05 +0200 Subject: [PATCH 300/376] ci: update README --- README.md | 4 +++- roles/keycloak_quarkus/README.md | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c5ee5cf..3827b90 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,9 @@ > **_NOTE:_ If you are Red Hat customer, install `redhat.sso` (for Red Hat Single Sign-On) or `redhat.rhbk` (for Red Hat Build of Keycloak) from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection.** + Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on) / [Red Hat Build of Keycloak](https://access.redhat.com/products/red-hat-build-of-keycloak). - + ## Ansible version compatibility @@ -39,6 +40,7 @@ collections: The keycloak collection also depends on the following python packages to be present on the controller host: * netaddr +* lxml A requirement file is provided to install: diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index a166725..1fb0cd1 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -1,8 +1,8 @@ keycloak_quarkus ================ - + Install [keycloak](https://keycloak.org/) >= 20.0.0 (quarkus) server configurations. - + Requirements ------------ From 35b3b090f61ff54687138496080f98260f98c548 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 2 Jul 2024 15:59:16 +0200 Subject: [PATCH 301/376] ci: update READMEs --- roles/keycloak_realm/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/roles/keycloak_realm/README.md b/roles/keycloak_realm/README.md index 73d823f..d6ce30c 100644 --- a/roles/keycloak_realm/README.md +++ b/roles/keycloak_realm/README.md @@ -1,8 +1,9 @@ keycloak_realm ============== + Create realms and clients in [keycloak](https://keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on) services. - + Role Defaults ------------- @@ -136,4 +137,4 @@ Author Information ------------------ * [Guido Grazioli](https://github.com/guidograzioli) -* [Romain Pelisse](https://github.com/rpelisse) \ No newline at end of file +* [Romain Pelisse](https://github.com/rpelisse) From 7c520dcdd2f4a424a52a5d8bc6522f17f707b41b Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Tue, 2 Jul 2024 14:23:37 +0000 Subject: [PATCH 302/376] Update changelog for release 2.4.1 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 8 ++++++++ changelogs/changelog.yaml | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d8fbfdd..1aed396 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,14 @@ middleware\_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.4.1 +====== + +Release Summary +--------------- + +Internal release, documentation or test changes only. + v2.4.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index e5de562..c841535 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -584,3 +584,9 @@ releases: - 232.yaml - 234.yaml release_date: '2024-06-04' + 2.4.1: + changes: + release_summary: Internal release, documentation or test changes only. + fragments: + - v2.4.1-devel_summary.yaml + release_date: '2024-07-02' From fa2319d5da0922a5161d8475b17b0c2c0d0457a8 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Tue, 2 Jul 2024 14:23:53 +0000 Subject: [PATCH 303/376] Bump version to 2.4.2 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 7ff57c6..2091f28 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.4.1" +version: "2.4.2" readme: README.md authors: - Romain Pelisse From 11aab0f5e2bc68f7b895de3f10e4a39e67639ed1 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 18 Jul 2024 12:53:49 +0200 Subject: [PATCH 304/376] add verify steps for quarkus/keycloak_realm --- molecule/quarkus/verify.yml | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index dd8490f..24c27aa 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -1,6 +1,8 @@ --- - name: Verify hosts: all + vars: + keycloak_admin_password: "remembertochangeme" tasks: - name: Populate service facts ansible.builtin.service_facts: @@ -84,3 +86,42 @@ changed_when: false failed_when: slurped_log.rc != 0 register: slurped_log + + - name: Verify token api call + ansible.builtin.uri: + url: "https://localhost:8443/realms/master/protocol/openid-connect/token" + method: POST + body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password" + validate_certs: no + register: keycloak_auth_response + until: keycloak_auth_response.status == 200 + retries: 2 + delay: 2 + + - name: "Get Clients" + ansible.builtin.uri: + url: "https://localhost:8443/admin/realms/TestRealm/clients" + headers: + validate_certs: false + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + register: keycloak_clients + + - name: Get client uuid + ansible.builtin.set_fact: + keycloak_client_uuid: "{{ ((keycloak_clients.json | selectattr('clientId', '==', 'TestClient')) | first).id }}" + + - name: "Get Client {{ keycloak_client_uuid }}" + ansible.builtin.uri: + url: "https://localhost:8443/admin/realms/TestRealm/clients/{{ keycloak_client_uuid }}" + headers: + validate_certs: false + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + register: keycloak_test_client + + - name: "Get Client roles" + ansible.builtin.uri: + url: "https://localhost:8443/admin/realms/TestRealm/clients/{{ keycloak_client_uuid }}/roles" + headers: + validate_certs: false + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + register: keycloak_test_client_roles \ No newline at end of file From a35c963a65c0a61ff7a2c65b13ee4e23baa894e4 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 18 Jul 2024 13:01:01 +0200 Subject: [PATCH 305/376] add verify steps for quarkus/keycloak_realm --- molecule/quarkus/verify.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 24c27aa..63769dc 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -89,7 +89,7 @@ - name: Verify token api call ansible.builtin.uri: - url: "https://localhost:8443/realms/master/protocol/openid-connect/token" + url: "https://instance:8443/realms/master/protocol/openid-connect/token" method: POST body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password" validate_certs: no @@ -100,7 +100,7 @@ - name: "Get Clients" ansible.builtin.uri: - url: "https://localhost:8443/admin/realms/TestRealm/clients" + url: "https://instance:8443/admin/realms/TestRealm/clients" headers: validate_certs: false Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" @@ -112,7 +112,7 @@ - name: "Get Client {{ keycloak_client_uuid }}" ansible.builtin.uri: - url: "https://localhost:8443/admin/realms/TestRealm/clients/{{ keycloak_client_uuid }}" + url: "https://instance:8443/admin/realms/TestRealm/clients/{{ keycloak_client_uuid }}" headers: validate_certs: false Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" @@ -120,7 +120,7 @@ - name: "Get Client roles" ansible.builtin.uri: - url: "https://localhost:8443/admin/realms/TestRealm/clients/{{ keycloak_client_uuid }}/roles" + url: "https://instance:8443/admin/realms/TestRealm/clients/{{ keycloak_client_uuid }}/roles" headers: validate_certs: false Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" From 34caf6a490e3762f2d6864c00683594ae89f9ecc Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 31 Jul 2024 17:18:30 +0200 Subject: [PATCH 306/376] add wait_for_port number parameter --- roles/keycloak_quarkus/README.md | 1 + roles/keycloak_quarkus/defaults/main.yml | 1 + roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/templates/keycloak.service.j2 | 2 +- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 1fb0cd1..01163cd 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -98,6 +98,7 @@ Role Defaults |`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` | |`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7800` | |`keycloak_quarkus_systemd_wait_for_port` | Whether systemd unit should wait for keycloak port before returning | `{{ keycloak_quarkus_ha_enabled }}` | +|`keycloak_quarkus_systemd_wait_for_port_number`| Which port the systemd unit should wait for | `{{ keycloak_quarkus_https_port }}` | |`keycloak_quarkus_systemd_wait_for_log` | Whether systemd unit should wait for service to be up in logs | `false` | |`keycloak_quarkus_systemd_wait_for_timeout`| How long to wait for service to be alive (seconds) | `60` | |`keycloak_quarkus_systemd_wait_for_delay`| Activation delay for service systemd unit (seconds) | `10` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 4f6deb3..f99e9ff 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -74,6 +74,7 @@ keycloak_quarkus_ha_discovery: "TCPPING" ### Enable database configuration, must be enabled when HA is configured keycloak_quarkus_db_enabled: "{{ keycloak_quarkus_ha_enabled }}" keycloak_quarkus_systemd_wait_for_port: "{{ keycloak_quarkus_ha_enabled }}" +keycloak_quarkus_systemd_wait_for_port_number: "{{ keycloak_quarkus_https_port }}" keycloak_quarkus_systemd_wait_for_log: false keycloak_quarkus_systemd_wait_for_timeout: 60 keycloak_quarkus_systemd_wait_for_delay: 10 diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 978ca7e..2c68460 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -386,6 +386,10 @@ argument_specs: description: 'Whether systemd unit should wait for keycloak port before returning' default: "{{ keycloak_quarkus_ha_enabled }}" type: "bool" + keycloak_quarkus_systemd_wait_for_port_number: + default: "{{ keycloak_quarkus_https_port }}" + description: "The port the systemd unit should wait for, by default the https port" + type: "int" keycloak_quarkus_systemd_wait_for_log: description: 'Whether systemd unit should wait for service to be up in logs' default: false diff --git a/roles/keycloak_quarkus/templates/keycloak.service.j2 b/roles/keycloak_quarkus/templates/keycloak.service.j2 index 9cabb69..96207ed 100644 --- a/roles/keycloak_quarkus/templates/keycloak.service.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.service.j2 @@ -23,7 +23,7 @@ RestartSec={{ keycloak_quarkus_service_restartsec }} AmbientCapabilities=CAP_NET_BIND_SERVICE {% endif %} {% if keycloak_quarkus_systemd_wait_for_port %} -ExecStartPost=/usr/bin/timeout {{ keycloak_quarkus_systemd_wait_for_timeout }} sh -c 'while ! ss -H -t -l -n sport = :{{ keycloak_quarkus_https_port }} | grep -q "^LISTEN.*:{{ keycloak_quarkus_https_port }}"; do sleep 1; done && /bin/sleep {{ keycloak_quarkus_systemd_wait_for_delay }}' +ExecStartPost=/usr/bin/timeout {{ keycloak_quarkus_systemd_wait_for_timeout }} sh -c 'while ! ss -H -t -l -n sport = :{{ keycloak_quarkus_systemd_wait_for_port_number }} | grep -q "^LISTEN.*:{{ keycloak_quarkus_systemd_wait_for_port_number }}"; do sleep 1; done && /bin/sleep {{ keycloak_quarkus_systemd_wait_for_delay }}' {% endif %} {% if keycloak_quarkus_systemd_wait_for_log %} ExecStartPost=/usr/bin/timeout {{ keycloak_quarkus_systemd_wait_for_timeout }} sh -c 'cat {{ keycloak.log.file }} | sed "/Profile.*activated/ q" && /bin/sleep {{ keycloak_quarkus_systemd_wait_for_delay }}' From f1702572059585bb97537deaa6a1096230314055 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 24 Sep 2024 09:21:10 +0200 Subject: [PATCH 307/376] Add local download path --- .ansible-lint | 1 + roles/keycloak_quarkus/README.md | 1 + roles/keycloak_quarkus/defaults/main.yml | 1 + roles/keycloak_quarkus/handlers/main.yml | 2 +- .../keycloak_quarkus/meta/argument_specs.yml | 18 ++++---- roles/keycloak_quarkus/tasks/bootstrapped.yml | 4 +- roles/keycloak_quarkus/tasks/config_store.yml | 6 +-- roles/keycloak_quarkus/tasks/install.yml | 13 ++---- roles/keycloak_quarkus/tasks/main.yml | 2 +- roles/keycloak_quarkus/tasks/prereqs.yml | 42 ++++++++++++++++++- .../keycloak_quarkus/tasks/rebuild_config.yml | 2 +- roles/keycloak_quarkus/tasks/restart.yml | 2 +- 12 files changed, 67 insertions(+), 27 deletions(-) diff --git a/.ansible-lint b/.ansible-lint index 9c2702e..e6607a4 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -34,6 +34,7 @@ warn_list: skip_list: - vars_should_not_be_used - file_is_small_enough + - file_has_valid_name - name[template] - var-naming[no-role-prefix] diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 01163cd..00c785f 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -37,6 +37,7 @@ Role Defaults |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | +|`keycloak_quarkus_download_path`| Path local to controller for offline/download of install archives | `{{ lookup('env', 'PWD') }}` | #### Service configuration diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index f99e9ff..b029fee 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -15,6 +15,7 @@ keycloak_quarkus_java_home: keycloak_quarkus_dest: /opt/keycloak keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" keycloak_quarkus_config_dir: "{{ keycloak_quarkus_home }}/conf" +keycloak_quarkus_download_path: "{{ lookup('env', 'PWD') }}" keycloak_quarkus_start_dev: false keycloak_quarkus_service_user: keycloak keycloak_quarkus_service_group: keycloak diff --git a/roles/keycloak_quarkus/handlers/main.yml b/roles/keycloak_quarkus/handlers/main.yml index 5851a71..37d65c5 100644 --- a/roles/keycloak_quarkus/handlers/main.yml +++ b/roles/keycloak_quarkus/handlers/main.yml @@ -10,7 +10,7 @@ ansible.builtin.include_tasks: file: "{{ keycloak_quarkus_restart_strategy if keycloak_quarkus_ha_enabled else 'restart.yml' }}" listen: "restart keycloak" -- name: "Print deprecation warning" +- name: "Display deprecation warning" ansible.builtin.fail: msg: "Deprecation warning: you are using the deprecated variable '{{ deprecated_variable | d('NotSet') }}', check docs on how to upgrade." failed_when: false diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 2c68460..34ec365 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -56,15 +56,15 @@ argument_specs: default: false description: "Ensure firewalld is running and configure keycloak ports" type: "bool" - keycloak_service_restart_always: + keycloak_quarkus_service_restart_always: default: false description: "systemd restart always behavior of service; takes precedence over keycloak_service_restart_on_failure if true" type: "bool" - keycloak_service_restart_on_failure: + keycloak_quarkus_service_restart_on_failure: default: false description: "systemd restart on-failure behavior of service" type: "bool" - keycloak_service_restartsec: + keycloak_quarkus_service_restartsec: default: "10s" description: "systemd RestartSec for service" type: "str" @@ -457,6 +457,14 @@ argument_specs: description: "Number of attempts for successful health check before failing" default: 25 type: 'int' + keycloak_quarkus_show_deprecation_warnings: + default: true + description: "Whether or not deprecation warnings should be shown" + type: "bool" + keycloak_quarkus_download_path: + description: "Path local to controller for offline/download of install archives" + default: "{{ lookup('env', 'PWD') }}" + type: "str" downstream: options: rhbk_version: @@ -487,10 +495,6 @@ argument_specs: default: false description: "Perform an offline install" type: "bool" - keycloak_quarkus_show_deprecation_warnings: - default: true - description: "Whether deprecation warnings should be shown" - type: "bool" rhbk_service_name: default: "rhbk" description: "systemd service name for Red Hat Build of Keycloak" diff --git a/roles/keycloak_quarkus/tasks/bootstrapped.yml b/roles/keycloak_quarkus/tasks/bootstrapped.yml index 46278ab..3cbc5c4 100644 --- a/roles/keycloak_quarkus/tasks/bootstrapped.yml +++ b/roles/keycloak_quarkus/tasks/bootstrapped.yml @@ -1,5 +1,5 @@ --- -- name: Write ansible custom facts +- name: Save ansible custom facts become: true ansible.builtin.template: src: keycloak.fact.j2 @@ -8,7 +8,7 @@ vars: bootstrapped: true -- name: Re-read custom facts +- name: Refresh custom facts ansible.builtin.setup: filter: ansible_local diff --git a/roles/keycloak_quarkus/tasks/config_store.yml b/roles/keycloak_quarkus/tasks/config_store.yml index 40acc65..2d8b39e 100644 --- a/roles/keycloak_quarkus/tasks/config_store.yml +++ b/roles/keycloak_quarkus/tasks/config_store.yml @@ -8,7 +8,7 @@ - name: "Initialize empty configuration key store" become: true # keytool doesn't allow creating an empty key store, so this is a hacky way around it - ansible.builtin.shell: | + ansible.builtin.shell: | # noqa blocked_modules shell is necessary here set -o nounset # abort on unbound variable set -o pipefail # do not hide errors within pipes set -o errexit # abort on nonzero exit status @@ -19,7 +19,7 @@ creates: "{{ keycloak_quarkus_config_key_store_file }}" - name: "Set configuration key store using keytool" - ansible.builtin.shell: | + ansible.builtin.shell: | # noqa blocked_modules shell is necessary here set -o nounset # abort on unbound variable set -o pipefail # do not hide errors within pipes @@ -36,7 +36,7 @@ fi echo {{ item.value | quote }} | keytool -noprompt -importpass -alias {{ item.key | quote }} -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }} -storetype PKCS12 - with_items: "{{ store_items }}" + loop: "{{ store_items }}" no_log: true become: true changed_when: true diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 7745031..809e07e 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -8,6 +8,7 @@ - keycloak_quarkus_archive is defined - keycloak_quarkus_download_url is defined - keycloak_quarkus_version is defined + - local_path is defined quiet: true - name: Check for an existing deployment @@ -52,14 +53,6 @@ register: archive_path ## download to controller -- name: Check local download archive path - ansible.builtin.stat: - path: "{{ lookup('env', 'PWD') }}" - register: local_path - delegate_to: localhost - run_once: true - become: false - - name: Download keycloak archive ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user url: "{{ keycloak_quarkus_download_url }}" @@ -244,7 +237,7 @@ no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or not item.restart else [] }}" -- name: "Upload local maven providers" +- name: "Copy maven providers" ansible.builtin.copy: src: "{{ local_path.stat.path }}/{{ item.id }}.jar" dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar" @@ -256,7 +249,7 @@ when: item.maven is defined no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" -- name: "Upload local providers" +- name: "Copy providers" ansible.builtin.copy: src: "{{ item.local_path }}" dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar" diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 2dadf61..bb86b2c 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -91,7 +91,7 @@ register: keycloak_service_status changed_when: false -- name: "Trigger bootstrapped notification: remove `keycloak_quarkus_admin_user[_pass]` env vars" +- name: "Notify to remove `keycloak_quarkus_admin_user[_pass]` env vars" when: - not ansible_local.keycloak.general.bootstrapped | default(false) | bool # it was not bootstrapped prior to the current role's execution - keycloak_service_status.status.ActiveState == "active" # but it is now diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 503b308..ae2dacf 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -43,10 +43,50 @@ vars: packages_list: "{{ keycloak_quarkus_prereq_package_list }}" +- name: Check local download archive path + ansible.builtin.stat: + path: "{{ keycloak_quarkus_download_path }}" + register: local_path + delegate_to: localhost + run_once: true + become: false + +- name: Validate local download path + ansible.builtin.assert: + that: + - local_path.stat.exists + - local_path.stat.readable + - keycloak_quarkus_offline_install or local_path.stat.writeable + quiet: true + fail_msg: "Defined controller path for downloading resource is incorrect: {{ keycloak_quarkus_download_path }}" + success_msg: "Will download resource to controller path: {{ local_path.stat.path }}" + delegate_to: localhost + run_once: true + +- name: Check downloaded archive if offline + ansible.builtin.stat: + path: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" + when: keycloak_quarkus_offline_install + register: local_archive_path_check + delegate_to: localhost + run_once: true + +- name: Validate local downloaded archive if offline + ansible.builtin.assert: + that: + - local_archive_path_check.stat.exists + - local_archive_path_check.stat.readable + quiet: true + fail_msg: "Configured for offline install but install archive not found at: {{ local_archive_path_check.stat.path }}" + success_msg: "Will install offline with expected archive: {{ local_archive_path_check.stat.path }}" + when: keycloak_quarkus_offline_install + delegate_to: localhost + run_once: true + - name: "Validate keytool" when: keycloak_quarkus_config_key_store_password | length > 0 block: - - name: "Attempt to run keytool" + - name: "Check run keytool" changed_when: false ansible.builtin.command: keytool -help register: keytool_check diff --git a/roles/keycloak_quarkus/tasks/rebuild_config.yml b/roles/keycloak_quarkus/tasks/rebuild_config.yml index 5d2247d..ac78504 100644 --- a/roles/keycloak_quarkus/tasks/rebuild_config.yml +++ b/roles/keycloak_quarkus/tasks/rebuild_config.yml @@ -1,7 +1,7 @@ --- # cf. https://www.keycloak.org/server/configuration#_optimize_the_keycloak_startup - name: "Rebuild {{ keycloak.service_name }} config" - ansible.builtin.shell: | + ansible.builtin.shell: | # noqa blocked_modules shell is necessary here {{ keycloak.home }}/bin/kc.sh build environment: PATH: "{{ keycloak_quarkus_java_home | default(keycloak_quarkus_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" diff --git a/roles/keycloak_quarkus/tasks/restart.yml b/roles/keycloak_quarkus/tasks/restart.yml index 2a1fabd..61356d5 100644 --- a/roles/keycloak_quarkus/tasks/restart.yml +++ b/roles/keycloak_quarkus/tasks/restart.yml @@ -16,7 +16,7 @@ delay: "{{ keycloak_quarkus_restart_health_check_delay }}" when: internal_force_health_check | default(keycloak_quarkus_restart_health_check) -- name: Pause to give distributed ispn caches time to (re-)replicate back onto first host +- name: Wait to give distributed ispn caches time to (re-)replicate back onto first host ansible.builtin.pause: seconds: "{{ keycloak_quarkus_restart_pause }}" when: From eb66d4a412528bfb4cb560a7b3ae730e97f8225f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 26 Sep 2024 10:22:28 +0200 Subject: [PATCH 308/376] update prereqs validation --- .ansible-lint | 1 + .gitignore | 1 + roles/keycloak_quarkus/tasks/prereqs.yml | 8 ++++---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.ansible-lint b/.ansible-lint index e6607a4..8e4b5ca 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -30,6 +30,7 @@ warn_list: - schema[meta] - key-order[task] - blocked_modules + - run-once[task] skip_list: - vars_should_not_be_used diff --git a/.gitignore b/.gitignore index f2ffea4..ce41aef 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ docs/_build/ changelogs/.plugin-cache.yaml *.pem *.key +*.p12 diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index ae2dacf..0835aab 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -58,8 +58,8 @@ - local_path.stat.readable - keycloak_quarkus_offline_install or local_path.stat.writeable quiet: true - fail_msg: "Defined controller path for downloading resource is incorrect: {{ keycloak_quarkus_download_path }}" - success_msg: "Will download resource to controller path: {{ local_path.stat.path }}" + fail_msg: "Defined controller path for downloading resources is incorrect or unreadable: {{ keycloak_quarkus_download_path }}" + success_msg: "Will download resource to controller path: {{ keycloak_quarkus_download_path }}" delegate_to: localhost run_once: true @@ -77,8 +77,8 @@ - local_archive_path_check.stat.exists - local_archive_path_check.stat.readable quiet: true - fail_msg: "Configured for offline install but install archive not found at: {{ local_archive_path_check.stat.path }}" - success_msg: "Will install offline with expected archive: {{ local_archive_path_check.stat.path }}" + fail_msg: "Configured for offline install but install archive not found at: {{ local_path.stat.path }}/{{ keycloak.bundle }}" + success_msg: "Will install offline with expected archive: {{ local_path.stat.path }}/{{ keycloak.bundle }}" when: keycloak_quarkus_offline_install delegate_to: localhost run_once: true From fc0ee5a89654324ead9a8a66809fa0418d28d122 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 26 Sep 2024 10:22:42 +0200 Subject: [PATCH 309/376] refactor default test for keycloak-quarkus offline --- molecule/default/converge.yml | 97 +++++++++++++++-------------------- molecule/default/prepare.yml | 28 +++++----- molecule/default/verify.yml | 69 +------------------------ 3 files changed, 57 insertions(+), 137 deletions(-) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index 07cd724..bb8c552 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -2,61 +2,46 @@ - name: Converge hosts: all vars: + keycloak_quarkus_show_deprecation_warnings: false + keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_admin_password: "remembertochangeme" - keycloak_jvm_package: java-11-openjdk-headless - keycloak_modcluster_enabled: True - keycloak_modcluster_urls: - - host: myhost1 - port: 16667 - - host: myhost2 - port: 16668 - keycloak_jboss_port_offset: 10 - keycloak_log_target: /tmp/keycloak + keycloak_quarkus_host: instance + keycloak_quarkus_log: file + keycloak_quarkus_log_level: debug + keycloak_quarkus_log_target: /tmp/keycloak + keycloak_quarkus_start_dev: True + keycloak_quarkus_proxy_mode: none + keycloak_quarkus_offline_install: true + keycloak_quarkus_download_path: /tmp/keycloak/ roles: - - role: keycloak - tasks: - - name: Keycloak Realm Role - ansible.builtin.include_role: - name: keycloak_realm - vars: - keycloak_client_default_roles: - - TestRoleAdmin - - TestRoleUser - keycloak_client_users: - - username: TestUser - password: password - client_roles: - - client: TestClient - role: TestRoleUser - realm: "{{ keycloak_realm }}" - - username: TestAdmin - password: password - client_roles: - - client: TestClient - role: TestRoleUser - realm: "{{ keycloak_realm }}" - - client: TestClient - role: TestRoleAdmin - realm: "{{ keycloak_realm }}" - keycloak_realm: TestRealm - keycloak_clients: - - name: TestClient - roles: "{{ keycloak_client_default_roles }}" - realm: "{{ keycloak_realm }}" - public_client: "{{ keycloak_client_public }}" - web_origins: "{{ keycloak_client_web_origins }}" - users: "{{ keycloak_client_users }}" - client_id: TestClient - attributes: - post.logout.redirect.uris: '/public/logout' - pre_tasks: - - name: "Retrieve assets server from env" - ansible.builtin.set_fact: - assets_server: "{{ lookup('env', 'MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" - - - name: "Set offline when assets server from env is defined" - ansible.builtin.set_fact: - sso_offline_install: True - when: - - assets_server is defined - - assets_server | length > 0 + - role: keycloak_quarkus + - role: keycloak_realm + keycloak_context: '' + keycloak_client_default_roles: + - TestRoleAdmin + - TestRoleUser + keycloak_client_users: + - username: TestUser + password: password + client_roles: + - client: TestClient + role: TestRoleUser + realm: "{{ keycloak_realm }}" + - username: TestAdmin + password: password + client_roles: + - client: TestClient + role: TestRoleUser + realm: "{{ keycloak_realm }}" + - client: TestClient + role: TestRoleAdmin + realm: "{{ keycloak_realm }}" + keycloak_realm: TestRealm + keycloak_clients: + - name: TestClient + roles: "{{ keycloak_client_default_roles }}" + realm: "{{ keycloak_realm }}" + public_client: "{{ keycloak_client_public }}" + web_origins: "{{ keycloak_client_web_origins }}" + users: "{{ keycloak_client_users }}" + client_id: TestClient diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index b707f6c..a50dfa4 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -12,18 +12,18 @@ - "{{ assets_server }}/sso/7.6.0/rh-sso-7.6.0-server-dist.zip" - "{{ assets_server }}/sso/7.6.1/rh-sso-7.6.1-patch.zip" - - name: Install JDK8 - become: yes - ansible.builtin.yum: - name: - - java-1.8.0-openjdk - state: present - when: ansible_facts['os_family'] == "RedHat" + - name: Create controller directory for downloads + ansible.builtin.file: # noqa risky-file-permissions delegated, uses controller host user + path: /tmp/keycloak + state: directory + mode: '0750' + delegate_to: localhost + run_once: true - - name: Install JDK8 - become: yes - ansible.builtin.apt: - name: - - openjdk-8-jdk - state: present - when: ansible_facts['os_family'] == "Debian" + - name: Download keycloak archive to controller directory + ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user + url: https://github.com/keycloak/keycloak/releases/download/24.0.4/keycloak-24.0.4.zip + dest: /tmp/keycloak + mode: '0640' + delegate_to: localhost + run_once: true diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 39e94c5..b880105 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -3,10 +3,7 @@ hosts: all vars: keycloak_admin_password: "remembertochangeme" - keycloak_jvm_package: java-11-openjdk-headless - keycloak_uri: "http://localhost:{{ 8080 + ( keycloak_jboss_port_offset | default(0) ) }}" - keycloak_management_port: "http://localhost:{{ 9990 + ( keycloak_jboss_port_offset | default(0) ) }}" - keycloak_jboss_port_offset: 10 + keycloak_uri: "http://localhost:8080" tasks: - name: Populate service facts ansible.builtin.service_facts: @@ -15,16 +12,9 @@ that: - ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["status"] == "enabled" - - name: Verify we are running on requested jvm # noqa blocked_modules command-instead-of-module - ansible.builtin.shell: | - set -o pipefail - ps -ef | grep '/etc/alternatives/jre_11/' | grep -v grep - args: - executable: /bin/bash - changed_when: no - name: Verify token api call ansible.builtin.uri: - url: "{{ keycloak_uri }}/auth/realms/master/protocol/openid-connect/token" + url: "{{ keycloak_uri }}/realms/master/protocol/openid-connect/token" method: POST body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password" validate_certs: no @@ -32,58 +22,3 @@ until: keycloak_auth_response.status == 200 retries: 2 delay: 2 - - name: Fetch openid-connect config - ansible.builtin.uri: - url: "{{ keycloak_uri }}/auth/realms/TestRealm/.well-known/openid-configuration" - method: GET - validate_certs: no - status_code: 200 - register: keycloak_openid_config - - name: Verify expected config - ansible.builtin.assert: - that: - - keycloak_openid_config.json.registration_endpoint == 'http://localhost:8080/auth/realms/TestRealm/clients-registrations/openid-connect' - - name: Get test realm clients - ansible.builtin.uri: - url: "{{ keycloak_uri }}/auth/admin/realms/TestRealm/clients" - method: GET - validate_certs: no - status_code: 200 - headers: - Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" - register: keycloak_query_clients - - name: Verify expected config - ansible.builtin.assert: - that: - - (keycloak_query_clients.json | selectattr('clientId','equalto','TestClient') | first)["attributes"]["post.logout.redirect.uris"] == '/public/logout' - - name: "Privilege escalation as some files/folders may requires it" - become: yes - block: - - name: Check log folder - ansible.builtin.stat: - path: "/tmp/keycloak" - register: keycloak_log_folder - - name: Check that keycloak log folder exists and is a link - ansible.builtin.assert: - that: - - keycloak_log_folder.stat.exists - - not keycloak_log_folder.stat.isdir - - keycloak_log_folder.stat.islnk - - name: Check log file - ansible.builtin.stat: - path: "/tmp/keycloak/server.log" - register: keycloak_log_file - - name: Check if keycloak file exists - ansible.builtin.assert: - that: - - keycloak_log_file.stat.exists - - not keycloak_log_file.stat.isdir - - name: Check default log folder - ansible.builtin.stat: - path: "/var/log/keycloak" - register: keycloak_default_log_folder - failed_when: false - - name: Check that default keycloak log folder doesn't exist - ansible.builtin.assert: - that: - - not keycloak_default_log_folder.stat.exists From b2edea87771fb59d46f2bb2ecc81fc91fd02c8ed Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 26 Sep 2024 10:22:54 +0200 Subject: [PATCH 310/376] linter --- molecule/quarkus/prepare.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 459bafa..21a0f30 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -12,14 +12,14 @@ - name: Create certificate request ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' delegate_to: localhost - changed_when: False + changed_when: false - name: Create vault directory become: true ansible.builtin.file: state: directory path: "/opt/keycloak/vault" - mode: 0755 + mode: '0755' - name: Make sure a jre is available (for keytool to prepare keystore) delegate_to: localhost @@ -41,4 +41,4 @@ ansible.builtin.copy: src: keystore.p12 dest: /opt/keycloak/vault/keystore.p12 - mode: 0444 + mode: '0444' From c8021f3102b156f077054a714a36648d01e03deb Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Thu, 26 Sep 2024 08:52:04 +0000 Subject: [PATCH 311/376] Update changelog for release 2.4.2 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 13 +++++++++++++ changelogs/changelog.yaml | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1aed396..7283c76 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,19 @@ middleware\_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v2.4.2 +====== + +Minor Changes +------------- + +- New parameter ``keycloak_quarkus_download_path`` `#239 `_ + +Bugfixes +-------- + +- Add wait_for_port number parameter `#237 `_ + v2.4.1 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index c841535..41a4076 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -590,3 +590,17 @@ releases: fragments: - v2.4.1-devel_summary.yaml release_date: '2024-07-02' + 2.4.2: + changes: + bugfixes: + - 'Add wait_for_port number parameter `#237 `_ + + ' + minor_changes: + - 'New parameter ``keycloak_quarkus_download_path`` `#239 `_ + + ' + fragments: + - 237.yaml + - 239.yaml + release_date: '2024-09-26' From ac4511bea9e39263fec9eec12dadb19feb356db3 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Thu, 26 Sep 2024 08:52:17 +0000 Subject: [PATCH 312/376] Bump version to 2.4.3 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 2091f28..a782353 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.4.2" +version: "2.4.3" readme: README.md authors: - Romain Pelisse From c6bb815979a875c6b0bdb1384c3d9c9c81ab25c9 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 14 Oct 2024 10:07:44 +0200 Subject: [PATCH 313/376] update keycloak modules --- .../identity/keycloak/keycloak.py | 1251 +++++++++++++++-- plugins/modules/keycloak_client.py | 289 +++- plugins/modules/keycloak_role.py | 97 +- plugins/modules/keycloak_user_federation.py | 257 ++-- 4 files changed, 1605 insertions(+), 289 deletions(-) diff --git a/plugins/module_utils/identity/keycloak/keycloak.py b/plugins/module_utils/identity/keycloak/keycloak.py index 15b6657..128b0fe 100644 --- a/plugins/module_utils/identity/keycloak/keycloak.py +++ b/plugins/module_utils/identity/keycloak/keycloak.py @@ -9,6 +9,7 @@ __metaclass__ = type import json import traceback +import copy from ansible.module_utils.urls import open_url from ansible.module_utils.six.moves.urllib.parse import urlencode, quote @@ -18,6 +19,7 @@ from ansible.module_utils.common.text.converters import to_native, to_text URL_REALM_INFO = "{url}/realms/{realm}" URL_REALMS = "{url}/admin/realms" URL_REALM = "{url}/admin/realms/{realm}" +URL_REALM_KEYS_METADATA = "{url}/admin/realms/{realm}/keys" URL_TOKEN = "{url}/realms/{realm}/protocol/openid-connect/token" URL_CLIENT = "{url}/admin/realms/{realm}/clients/{id}" @@ -27,6 +29,9 @@ URL_CLIENT_ROLES = "{url}/admin/realms/{realm}/clients/{id}/roles" URL_CLIENT_ROLE = "{url}/admin/realms/{realm}/clients/{id}/roles/{name}" URL_CLIENT_ROLE_COMPOSITES = "{url}/admin/realms/{realm}/clients/{id}/roles/{name}/composites" +URL_CLIENT_ROLE_SCOPE_CLIENTS = "{url}/admin/realms/{realm}/clients/{id}/scope-mappings/clients/{scopeid}" +URL_CLIENT_ROLE_SCOPE_REALM = "{url}/admin/realms/{realm}/clients/{id}/scope-mappings/realm" + URL_REALM_ROLES = "{url}/admin/realms/{realm}/roles" URL_REALM_ROLE = "{url}/admin/realms/{realm}/roles/{name}" URL_REALM_ROLEMAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings/realm" @@ -49,16 +54,36 @@ URL_CLIENTSCOPE = "{url}/admin/realms/{realm}/client-scopes/{id}" URL_CLIENTSCOPE_PROTOCOLMAPPERS = "{url}/admin/realms/{realm}/client-scopes/{id}/protocol-mappers/models" URL_CLIENTSCOPE_PROTOCOLMAPPER = "{url}/admin/realms/{realm}/client-scopes/{id}/protocol-mappers/models/{mapper_id}" +URL_DEFAULT_CLIENTSCOPES = "{url}/admin/realms/{realm}/default-default-client-scopes" +URL_DEFAULT_CLIENTSCOPE = "{url}/admin/realms/{realm}/default-default-client-scopes/{id}" +URL_OPTIONAL_CLIENTSCOPES = "{url}/admin/realms/{realm}/default-optional-client-scopes" +URL_OPTIONAL_CLIENTSCOPE = "{url}/admin/realms/{realm}/default-optional-client-scopes/{id}" + +URL_CLIENT_DEFAULT_CLIENTSCOPES = "{url}/admin/realms/{realm}/clients/{cid}/default-client-scopes" +URL_CLIENT_DEFAULT_CLIENTSCOPE = "{url}/admin/realms/{realm}/clients/{cid}/default-client-scopes/{id}" +URL_CLIENT_OPTIONAL_CLIENTSCOPES = "{url}/admin/realms/{realm}/clients/{cid}/optional-client-scopes" +URL_CLIENT_OPTIONAL_CLIENTSCOPE = "{url}/admin/realms/{realm}/clients/{cid}/optional-client-scopes/{id}" + URL_CLIENT_GROUP_ROLEMAPPINGS = "{url}/admin/realms/{realm}/groups/{id}/role-mappings/clients/{client}" URL_CLIENT_GROUP_ROLEMAPPINGS_AVAILABLE = "{url}/admin/realms/{realm}/groups/{id}/role-mappings/clients/{client}/available" URL_CLIENT_GROUP_ROLEMAPPINGS_COMPOSITE = "{url}/admin/realms/{realm}/groups/{id}/role-mappings/clients/{client}/composite" URL_USERS = "{url}/admin/realms/{realm}/users" +URL_USER = "{url}/admin/realms/{realm}/users/{id}" +URL_USER_ROLE_MAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings" +URL_USER_REALM_ROLE_MAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings/realm" +URL_USER_CLIENTS_ROLE_MAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients" +URL_USER_CLIENT_ROLE_MAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client_id}" +URL_USER_GROUPS = "{url}/admin/realms/{realm}/users/{id}/groups" +URL_USER_GROUP = "{url}/admin/realms/{realm}/users/{id}/groups/{group_id}" + URL_CLIENT_SERVICE_ACCOUNT_USER = "{url}/admin/realms/{realm}/clients/{id}/service-account-user" URL_CLIENT_USER_ROLEMAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client}" 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_REALM_GROUP_ROLEMAPPINGS = "{url}/admin/realms/{realm}/groups/{group}/role-mappings/realm" + URL_CLIENTSECRET = "{url}/admin/realms/{realm}/clients/{id}/client-secret" URL_AUTHENTICATION_FLOWS = "{url}/admin/realms/{realm}/authentication/flows" @@ -71,6 +96,9 @@ URL_AUTHENTICATION_EXECUTION_CONFIG = "{url}/admin/realms/{realm}/authentication URL_AUTHENTICATION_EXECUTION_RAISE_PRIORITY = "{url}/admin/realms/{realm}/authentication/executions/{id}/raise-priority" URL_AUTHENTICATION_EXECUTION_LOWER_PRIORITY = "{url}/admin/realms/{realm}/authentication/executions/{id}/lower-priority" URL_AUTHENTICATION_CONFIG = "{url}/admin/realms/{realm}/authentication/config/{id}" +URL_AUTHENTICATION_REGISTER_REQUIRED_ACTION = "{url}/admin/realms/{realm}/authentication/register-required-action" +URL_AUTHENTICATION_REQUIRED_ACTIONS = "{url}/admin/realms/{realm}/authentication/required-actions" +URL_AUTHENTICATION_REQUIRED_ACTIONS_ALIAS = "{url}/admin/realms/{realm}/authentication/required-actions/{alias}" URL_IDENTITY_PROVIDERS = "{url}/admin/realms/{realm}/identity-provider/instances" URL_IDENTITY_PROVIDER = "{url}/admin/realms/{realm}/identity-provider/instances/{alias}" @@ -80,6 +108,23 @@ URL_IDENTITY_PROVIDER_MAPPER = "{url}/admin/realms/{realm}/identity-provider/ins URL_COMPONENTS = "{url}/admin/realms/{realm}/components" URL_COMPONENT = "{url}/admin/realms/{realm}/components/{id}" +URL_AUTHZ_AUTHORIZATION_SCOPE = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/scope/{id}" +URL_AUTHZ_AUTHORIZATION_SCOPES = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/scope" + +# This URL is used for: +# - Querying client authorization permissions +# - Removing client authorization permissions +URL_AUTHZ_POLICIES = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/policy" +URL_AUTHZ_POLICY = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/policy/{id}" + +URL_AUTHZ_PERMISSION = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/permission/{permission_type}/{id}" +URL_AUTHZ_PERMISSIONS = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/permission/{permission_type}" + +URL_AUTHZ_RESOURCES = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/resource" + +URL_AUTHZ_CUSTOM_POLICY = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/policy/{policy_type}" +URL_AUTHZ_CUSTOM_POLICIES = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/policy" + def keycloak_argument_spec(): """ @@ -140,8 +185,7 @@ def get_token(module_params): 'password': auth_password, } # Remove empty items, for instance missing client_secret - payload = dict( - (k, v) for k, v in temp_payload.items() if v is not None) + payload = {k: v for k, v in temp_payload.items() if v is not None} try: r = json.loads(to_native(open_url(auth_url, method='POST', validate_certs=validate_certs, http_agent=http_agent, timeout=connection_timeout, @@ -194,24 +238,30 @@ def is_struct_included(struct1, struct2, exclude=None): Return True if all element of dict 1 are present in dict 2, return false otherwise. """ if isinstance(struct1, list) and isinstance(struct2, list): + if not struct1 and not struct2: + return True for item1 in struct1: if isinstance(item1, (list, dict)): for item2 in struct2: - if not is_struct_included(item1, item2, exclude): - return False + if is_struct_included(item1, item2, exclude): + break + else: + return False else: if item1 not in struct2: return False return True elif isinstance(struct1, dict) and isinstance(struct2, dict): + if not struct1 and not struct2: + return True try: for key in struct1: if not (exclude and key in exclude): if not is_struct_included(struct1[key], struct2[key], exclude): return False - return True except KeyError: return False + return True elif isinstance(struct1, bool) and isinstance(struct2, bool): return struct1 == struct2 else: @@ -247,8 +297,39 @@ class KeycloakAPI(object): if e.code == 404: return None else: - self.module.fail_json(msg='Could not obtain realm %s: %s' % (realm, str(e)), - exception=traceback.format_exc()) + self.fail_open_url(e, msg='Could not obtain realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) + except ValueError as e: + self.module.fail_json(msg='API returned incorrect JSON when trying to obtain realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) + except Exception as e: + self.module.fail_json(msg='Could not obtain realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) + + def get_realm_keys_metadata_by_id(self, realm='master'): + """Obtain realm public info by id + + :param realm: realm id + + :return: None, or a 'KeysMetadataRepresentation' + (https://www.keycloak.org/docs-api/latest/rest-api/index.html#KeysMetadataRepresentation) + -- a dict containing the keys 'active' and 'keys', the former containing a mapping + from algorithms to key-ids, the latter containing a list of dicts with key + information. + """ + realm_keys_metadata_url = URL_REALM_KEYS_METADATA.format(url=self.baseurl, realm=realm) + + try: + return json.loads(to_native(open_url(realm_keys_metadata_url, method='GET', http_agent=self.http_agent, 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.fail_open_url(e, msg='Could not obtain realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) except ValueError as e: self.module.fail_json(msg='API returned incorrect JSON when trying to obtain realm %s: %s' % (realm, str(e)), exception=traceback.format_exc()) @@ -272,8 +353,8 @@ class KeycloakAPI(object): if e.code == 404: return None else: - self.module.fail_json(msg='Could not obtain realm %s: %s' % (realm, str(e)), - exception=traceback.format_exc()) + self.fail_open_url(e, msg='Could not obtain realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) except ValueError as e: self.module.fail_json(msg='API returned incorrect JSON when trying to obtain realm %s: %s' % (realm, str(e)), exception=traceback.format_exc()) @@ -293,8 +374,8 @@ class KeycloakAPI(object): return open_url(realm_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(realmrep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not update realm %s: %s' % (realm, str(e)), - exception=traceback.format_exc()) + self.fail_open_url(e, msg='Could not update realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) def create_realm(self, realmrep): """ Create a realm in keycloak @@ -307,8 +388,8 @@ class KeycloakAPI(object): return open_url(realm_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(realmrep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not create realm %s: %s' % (realmrep['id'], str(e)), - exception=traceback.format_exc()) + self.fail_open_url(e, msg='Could not create realm %s: %s' % (realmrep['id'], str(e)), + exception=traceback.format_exc()) def delete_realm(self, realm="master"): """ Delete a realm from Keycloak @@ -322,8 +403,8 @@ class KeycloakAPI(object): return open_url(realm_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not delete realm %s: %s' % (realm, str(e)), - exception=traceback.format_exc()) + self.fail_open_url(e, msg='Could not delete realm %s: %s' % (realm, str(e)), + exception=traceback.format_exc()) def get_clients(self, realm='master', filter=None): """ Obtains client representations for clients in a realm @@ -344,7 +425,7 @@ class KeycloakAPI(object): self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of clients for realm %s: %s' % (realm, str(e))) except Exception as e: - self.module.fail_json(msg='Could not obtain list of clients for realm %s: %s' + self.fail_open_url(e, msg='Could not obtain list of clients for realm %s: %s' % (realm, str(e))) def get_client_by_clientid(self, client_id, realm='master'): @@ -377,7 +458,7 @@ class KeycloakAPI(object): if e.code == 404: return None else: - self.module.fail_json(msg='Could not obtain client %s for realm %s: %s' + self.fail_open_url(e, msg='Could not obtain client %s for realm %s: %s' % (id, realm, str(e))) except ValueError as e: self.module.fail_json(msg='API returned incorrect JSON when trying to obtain client %s for realm %s: %s' @@ -412,7 +493,7 @@ class KeycloakAPI(object): return open_url(client_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(clientrep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not update client %s in realm %s: %s' + self.fail_open_url(e, msg='Could not update client %s in realm %s: %s' % (id, realm, str(e))) def create_client(self, clientrep, realm="master"): @@ -427,7 +508,7 @@ class KeycloakAPI(object): return open_url(client_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(clientrep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not create client %s in realm %s: %s' + self.fail_open_url(e, msg='Could not create client %s in realm %s: %s' % (clientrep['clientId'], realm, str(e))) def delete_client(self, id, realm="master"): @@ -443,7 +524,7 @@ class KeycloakAPI(object): return open_url(client_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not delete client %s in realm %s: %s' + self.fail_open_url(e, msg='Could not delete client %s in realm %s: %s' % (id, realm, str(e))) def get_client_roles_by_id(self, cid, realm="master"): @@ -459,7 +540,7 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except Exception as e: - self.module.fail_json(msg="Could not fetch rolemappings for client %s in realm %s: %s" + self.fail_open_url(e, msg="Could not fetch rolemappings for client %s in realm %s: %s" % (cid, realm, str(e))) def get_client_role_id_by_name(self, cid, name, realm="master"): @@ -494,12 +575,12 @@ class KeycloakAPI(object): if rid == role['id']: return role except Exception as e: - self.module.fail_json(msg="Could not fetch rolemappings for client %s in group %s, realm %s: %s" + self.fail_open_url(e, msg="Could not fetch rolemappings for client %s in group %s, realm %s: %s" % (cid, gid, realm, str(e))) return None def get_client_group_available_rolemappings(self, gid, cid, realm="master"): - """ Fetch the available role of a client in a specified goup on the Keycloak server. + """ Fetch the available role of a client in a specified group on the Keycloak server. :param gid: ID of the group from which to obtain the rolemappings. :param cid: ID of the client from which to obtain the rolemappings. @@ -512,7 +593,7 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except Exception as e: - self.module.fail_json(msg="Could not fetch available rolemappings for client %s in group %s, realm %s: %s" + self.fail_open_url(e, msg="Could not fetch available rolemappings for client %s in group %s, realm %s: %s" % (cid, gid, realm, str(e))) def get_client_group_composite_rolemappings(self, gid, cid, realm="master"): @@ -529,7 +610,7 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except Exception as e: - self.module.fail_json(msg="Could not fetch available rolemappings for client %s in group %s, realm %s: %s" + self.fail_open_url(e, msg="Could not fetch available rolemappings for client %s in group %s, realm %s: %s" % (cid, gid, realm, str(e))) def get_role_by_id(self, rid, realm="master"): @@ -545,7 +626,7 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except Exception as e: - self.module.fail_json(msg="Could not fetch role for id %s in realm %s: %s" + self.fail_open_url(e, msg="Could not fetch role for id %s in realm %s: %s" % (rid, realm, str(e))) def get_client_roles_by_id_composite_rolemappings(self, rid, cid, realm="master"): @@ -562,7 +643,7 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except Exception as e: - self.module.fail_json(msg="Could not fetch role for id %s and cid %s in realm %s: %s" + self.fail_open_url(e, msg="Could not fetch role for id %s and cid %s in realm %s: %s" % (rid, cid, realm, str(e))) def add_client_roles_by_id_composite_rolemapping(self, rid, roles_rep, realm="master"): @@ -578,11 +659,43 @@ class KeycloakAPI(object): open_url(available_rolemappings_url, method="POST", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(roles_rep), validate_certs=self.validate_certs, timeout=self.connection_timeout) except Exception as e: - self.module.fail_json(msg="Could not assign roles to composite role %s and realm %s: %s" + self.fail_open_url(e, msg="Could not assign roles to composite role %s and realm %s: %s" % (rid, realm, str(e))) + def add_group_realm_rolemapping(self, gid, role_rep, realm="master"): + """ Add the specified realm role to specified group on the Keycloak server. + + :param gid: ID of the group to add the role mapping. + :param role_rep: Representation of the role to assign. + :param realm: Realm from which to obtain the rolemappings. + :return: None. + """ + url = URL_REALM_GROUP_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, group=gid) + try: + open_url(url, method="POST", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), + validate_certs=self.validate_certs, timeout=self.connection_timeout) + except Exception as e: + self.fail_open_url(e, msg="Could add realm role mappings for group %s, realm %s: %s" + % (gid, realm, str(e))) + + def delete_group_realm_rolemapping(self, gid, role_rep, realm="master"): + """ Delete the specified realm role from the specified group on the Keycloak server. + + :param gid: ID of the group from which to obtain the rolemappings. + :param role_rep: Representation of the role to assign. + :param realm: Realm from which to obtain the rolemappings. + :return: None. + """ + url = URL_REALM_GROUP_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, group=gid) + try: + open_url(url, method="DELETE", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), + validate_certs=self.validate_certs, timeout=self.connection_timeout) + except Exception as e: + self.fail_open_url(e, msg="Could not delete realm role mappings for group %s, realm %s: %s" + % (gid, realm, str(e))) + def add_group_rolemapping(self, gid, cid, role_rep, realm="master"): - """ Fetch the composite role of a client in a specified goup on the Keycloak server. + """ Fetch the composite role of a client in a specified group on the Keycloak server. :param gid: ID of the group from which to obtain the rolemappings. :param cid: ID of the client from which to obtain the rolemappings. @@ -595,7 +708,7 @@ class KeycloakAPI(object): open_url(available_rolemappings_url, method="POST", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), validate_certs=self.validate_certs, timeout=self.connection_timeout) except Exception as e: - self.module.fail_json(msg="Could not fetch available rolemappings for client %s in group %s, realm %s: %s" + self.fail_open_url(e, msg="Could not fetch available rolemappings for client %s in group %s, realm %s: %s" % (cid, gid, realm, str(e))) def delete_group_rolemapping(self, gid, cid, role_rep, realm="master"): @@ -612,7 +725,7 @@ class KeycloakAPI(object): open_url(available_rolemappings_url, method="DELETE", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), validate_certs=self.validate_certs, timeout=self.connection_timeout) except Exception as e: - self.module.fail_json(msg="Could not delete available rolemappings for client %s in group %s, realm %s: %s" + self.fail_open_url(e, msg="Could not delete available rolemappings for client %s in group %s, realm %s: %s" % (cid, gid, realm, str(e))) def get_client_user_rolemapping_by_id(self, uid, cid, rid, realm='master'): @@ -633,7 +746,7 @@ class KeycloakAPI(object): if rid == role['id']: return role except Exception as e: - self.module.fail_json(msg="Could not fetch rolemappings for client %s and user %s, realm %s: %s" + self.fail_open_url(e, msg="Could not fetch rolemappings for client %s and user %s, realm %s: %s" % (cid, uid, realm, str(e))) return None @@ -651,7 +764,7 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except Exception as e: - self.module.fail_json(msg="Could not fetch effective rolemappings for client %s and user %s, realm %s: %s" + self.fail_open_url(e, msg="Could not fetch effective rolemappings for client %s and user %s, realm %s: %s" % (cid, uid, realm, str(e))) def get_client_user_composite_rolemappings(self, uid, cid, realm="master"): @@ -668,7 +781,7 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except Exception as e: - self.module.fail_json(msg="Could not fetch available rolemappings for user %s of realm %s: %s" + self.fail_open_url(e, msg="Could not fetch available rolemappings for user %s of realm %s: %s" % (uid, realm, str(e))) def get_realm_user_rolemapping_by_id(self, uid, rid, realm='master'): @@ -688,7 +801,7 @@ class KeycloakAPI(object): if rid == role['id']: return role except Exception as e: - self.module.fail_json(msg="Could not fetch rolemappings for user %s, realm %s: %s" + self.fail_open_url(e, msg="Could not fetch rolemappings for user %s, realm %s: %s" % (uid, realm, str(e))) return None @@ -705,7 +818,7 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except Exception as e: - self.module.fail_json(msg="Could not fetch available rolemappings for user %s of realm %s: %s" + self.fail_open_url(e, msg="Could not fetch available rolemappings for user %s of realm %s: %s" % (uid, realm, str(e))) def get_realm_user_composite_rolemappings(self, uid, realm="master"): @@ -721,7 +834,7 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except Exception as e: - self.module.fail_json(msg="Could not fetch effective rolemappings for user %s, realm %s: %s" + self.fail_open_url(e, msg="Could not fetch effective rolemappings for user %s, realm %s: %s" % (uid, realm, str(e))) def get_user_by_username(self, username, realm="master"): @@ -734,13 +847,21 @@ class KeycloakAPI(object): users_url = URL_USERS.format(url=self.baseurl, realm=realm) users_url += '?username=%s&exact=true' % username try: - return json.loads(to_native(open_url(users_url, method='GET', headers=self.restheaders, timeout=self.connection_timeout, - validate_certs=self.validate_certs).read())) + userrep = None + users = json.loads(to_native(open_url(users_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + for user in users: + if user['username'] == username: + userrep = user + break + return userrep + except ValueError as e: self.module.fail_json(msg='API returned incorrect JSON when trying to obtain the user for realm %s and username %s: %s' % (realm, username, str(e))) except Exception as e: - self.module.fail_json(msg='Could not obtain the user for realm %s and username %s: %s' + self.fail_open_url(e, msg='Could not obtain the user for realm %s and username %s: %s' % (realm, username, str(e))) def get_service_account_user_by_client_id(self, client_id, realm="master"): @@ -754,13 +875,14 @@ class KeycloakAPI(object): service_account_user_url = URL_CLIENT_SERVICE_ACCOUNT_USER.format(url=self.baseurl, realm=realm, id=cid) try: - return json.loads(to_native(open_url(service_account_user_url, method='GET', headers=self.restheaders, timeout=self.connection_timeout, + return json.loads(to_native(open_url(service_account_user_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except ValueError as e: self.module.fail_json(msg='API returned incorrect JSON when trying to obtain the service-account-user for realm %s and client_id %s: %s' % (realm, client_id, str(e))) except Exception as e: - self.module.fail_json(msg='Could not obtain the service-account-user for realm %s and client_id %s: %s' + self.fail_open_url(e, msg='Could not obtain the service-account-user for realm %s and client_id %s: %s' % (realm, client_id, str(e))) def add_user_rolemapping(self, uid, cid, role_rep, realm="master"): @@ -778,7 +900,7 @@ class KeycloakAPI(object): open_url(user_realm_rolemappings_url, method="POST", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), validate_certs=self.validate_certs, timeout=self.connection_timeout) except Exception as e: - self.module.fail_json(msg="Could not map roles to userId %s for realm %s and roles %s: %s" + self.fail_open_url(e, msg="Could not map roles to userId %s for realm %s and roles %s: %s" % (uid, realm, json.dumps(role_rep), str(e))) else: user_client_rolemappings_url = URL_CLIENT_USER_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, id=uid, client=cid) @@ -786,7 +908,7 @@ class KeycloakAPI(object): open_url(user_client_rolemappings_url, method="POST", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), validate_certs=self.validate_certs, timeout=self.connection_timeout) except Exception as e: - self.module.fail_json(msg="Could not map roles to userId %s for client %s, realm %s and roles %s: %s" + self.fail_open_url(e, msg="Could not map roles to userId %s for client %s, realm %s and roles %s: %s" % (cid, uid, realm, json.dumps(role_rep), str(e))) def delete_user_rolemapping(self, uid, cid, role_rep, realm="master"): @@ -804,7 +926,7 @@ class KeycloakAPI(object): open_url(user_realm_rolemappings_url, method="DELETE", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), validate_certs=self.validate_certs, timeout=self.connection_timeout) except Exception as e: - self.module.fail_json(msg="Could not remove roles %s from userId %s, realm %s: %s" + self.fail_open_url(e, msg="Could not remove roles %s from userId %s, realm %s: %s" % (json.dumps(role_rep), uid, realm, str(e))) else: user_client_rolemappings_url = URL_CLIENT_USER_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, id=uid, client=cid) @@ -812,7 +934,7 @@ class KeycloakAPI(object): open_url(user_client_rolemappings_url, method="DELETE", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), validate_certs=self.validate_certs, timeout=self.connection_timeout) except Exception as e: - self.module.fail_json(msg="Could not remove roles %s for client %s from userId %s, realm %s: %s" + self.fail_open_url(e, msg="Could not remove roles %s for client %s from userId %s, realm %s: %s" % (json.dumps(role_rep), cid, uid, realm, str(e))) def get_client_templates(self, realm='master'): @@ -830,7 +952,7 @@ class KeycloakAPI(object): self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of client templates for realm %s: %s' % (realm, str(e))) except Exception as e: - self.module.fail_json(msg='Could not obtain list of client templates for realm %s: %s' + self.fail_open_url(e, msg='Could not obtain list of client templates for realm %s: %s' % (realm, str(e))) def get_client_template_by_id(self, id, realm='master'): @@ -849,7 +971,7 @@ class KeycloakAPI(object): self.module.fail_json(msg='API returned incorrect JSON when trying to obtain client templates %s for realm %s: %s' % (id, realm, str(e))) except Exception as e: - self.module.fail_json(msg='Could not obtain client template %s for realm %s: %s' + self.fail_open_url(e, msg='Could not obtain client template %s for realm %s: %s' % (id, realm, str(e))) def get_client_template_by_name(self, name, realm='master'): @@ -892,7 +1014,7 @@ class KeycloakAPI(object): return open_url(url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(clienttrep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not update client template %s in realm %s: %s' + self.fail_open_url(e, msg='Could not update client template %s in realm %s: %s' % (id, realm, str(e))) def create_client_template(self, clienttrep, realm="master"): @@ -907,7 +1029,7 @@ class KeycloakAPI(object): return open_url(url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(clienttrep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not create client template %s in realm %s: %s' + self.fail_open_url(e, msg='Could not create client template %s in realm %s: %s' % (clienttrep['clientId'], realm, str(e))) def delete_client_template(self, id, realm="master"): @@ -923,7 +1045,7 @@ class KeycloakAPI(object): return open_url(url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not delete client template %s in realm %s: %s' + self.fail_open_url(e, msg='Could not delete client template %s in realm %s: %s' % (id, realm, str(e))) def get_clientscopes(self, realm="master"): @@ -941,7 +1063,7 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except Exception as e: - self.module.fail_json(msg="Could not fetch list of clientscopes in realm %s: %s" + self.fail_open_url(e, msg="Could not fetch list of clientscopes in realm %s: %s" % (realm, str(e))) def get_clientscope_by_clientscopeid(self, cid, realm="master"): @@ -963,7 +1085,7 @@ class KeycloakAPI(object): if e.code == 404: return None else: - self.module.fail_json(msg="Could not fetch clientscope %s in realm %s: %s" + self.fail_open_url(e, msg="Could not fetch clientscope %s in realm %s: %s" % (cid, realm, str(e))) except Exception as e: self.module.fail_json(msg="Could not clientscope group %s in realm %s: %s" @@ -1004,7 +1126,7 @@ class KeycloakAPI(object): return open_url(clientscopes_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(clientscoperep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg="Could not create clientscope %s in realm %s: %s" + self.fail_open_url(e, msg="Could not create clientscope %s in realm %s: %s" % (clientscoperep['name'], realm, str(e))) def update_clientscope(self, clientscoperep, realm="master"): @@ -1020,7 +1142,7 @@ class KeycloakAPI(object): data=json.dumps(clientscoperep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not update clientscope %s in realm %s: %s' + self.fail_open_url(e, msg='Could not update clientscope %s in realm %s: %s' % (clientscoperep['name'], realm, str(e))) def delete_clientscope(self, name=None, cid=None, realm="master"): @@ -1058,7 +1180,7 @@ class KeycloakAPI(object): validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg="Unable to delete clientscope %s: %s" % (cid, str(e))) + self.fail_open_url(e, msg="Unable to delete clientscope %s: %s" % (cid, str(e))) def get_clientscope_protocolmappers(self, cid, realm="master"): """ Fetch the name and ID of all clientscopes on the Keycloak server. @@ -1076,7 +1198,7 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except Exception as e: - self.module.fail_json(msg="Could not fetch list of protocolmappers in realm %s: %s" + self.fail_open_url(e, msg="Could not fetch list of protocolmappers in realm %s: %s" % (realm, str(e))) def get_clientscope_protocolmapper_by_protocolmapperid(self, pid, cid, realm="master"): @@ -1100,7 +1222,7 @@ class KeycloakAPI(object): if e.code == 404: return None else: - self.module.fail_json(msg="Could not fetch protocolmapper %s in realm %s: %s" + self.fail_open_url(e, msg="Could not fetch protocolmapper %s in realm %s: %s" % (pid, realm, str(e))) except Exception as e: self.module.fail_json(msg="Could not fetch protocolmapper %s in realm %s: %s" @@ -1143,7 +1265,7 @@ class KeycloakAPI(object): return open_url(protocolmappers_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(mapper_rep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg="Could not create protocolmapper %s in realm %s: %s" + self.fail_open_url(e, msg="Could not create protocolmapper %s in realm %s: %s" % (mapper_rep['name'], realm, str(e))) def update_clientscope_protocolmappers(self, cid, mapper_rep, realm="master"): @@ -1160,9 +1282,134 @@ class KeycloakAPI(object): data=json.dumps(mapper_rep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not update protocolmappers for clientscope %s in realm %s: %s' + self.fail_open_url(e, msg='Could not update protocolmappers for clientscope %s in realm %s: %s' % (mapper_rep, realm, str(e))) + def get_default_clientscopes(self, realm, client_id=None): + """Fetch the name and ID of all clientscopes on the Keycloak server. + + To fetch the full data of the client scope, make a subsequent call to + get_clientscope_by_clientscopeid, passing in the ID of the client scope you wish to return. + + :param realm: Realm in which the clientscope resides. + :param client_id: The client in which the clientscope resides. + :return The default clientscopes of this realm or client + """ + url = URL_DEFAULT_CLIENTSCOPES if client_id is None else URL_CLIENT_DEFAULT_CLIENTSCOPES + return self._get_clientscopes_of_type(realm, url, 'default', client_id) + + def get_optional_clientscopes(self, realm, client_id=None): + """Fetch the name and ID of all clientscopes on the Keycloak server. + + To fetch the full data of the client scope, make a subsequent call to + get_clientscope_by_clientscopeid, passing in the ID of the client scope you wish to return. + + :param realm: Realm in which the clientscope resides. + :param client_id: The client in which the clientscope resides. + :return The optional clientscopes of this realm or client + """ + url = URL_OPTIONAL_CLIENTSCOPES if client_id is None else URL_CLIENT_OPTIONAL_CLIENTSCOPES + return self._get_clientscopes_of_type(realm, url, 'optional', client_id) + + def _get_clientscopes_of_type(self, realm, url_template, scope_type, client_id=None): + """Fetch the name and ID of all clientscopes on the Keycloak server. + + To fetch the full data of the client scope, make a subsequent call to + get_clientscope_by_clientscopeid, passing in the ID of the client scope you wish to return. + + :param realm: Realm in which the clientscope resides. + :param url_template the template for the right type + :param scope_type this can be either optional or default + :param client_id: The client in which the clientscope resides. + :return The clientscopes of the specified type of this realm + """ + if client_id is None: + clientscopes_url = url_template.format(url=self.baseurl, realm=realm) + try: + return json.loads(to_native(open_url(clientscopes_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) + except Exception as e: + self.fail_open_url(e, msg="Could not fetch list of %s clientscopes in realm %s: %s" % (scope_type, realm, str(e))) + else: + cid = self.get_client_id(client_id=client_id, realm=realm) + clientscopes_url = url_template.format(url=self.baseurl, realm=realm, cid=cid) + try: + return json.loads(to_native(open_url(clientscopes_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) + except Exception as e: + self.fail_open_url(e, msg="Could not fetch list of %s clientscopes in client %s: %s" % (scope_type, client_id, clientscopes_url)) + + def _decide_url_type_clientscope(self, client_id=None, scope_type="default"): + """Decides which url to use. + :param scope_type this can be either optional or default + :param client_id: The client in which the clientscope resides. + """ + if client_id is None: + if scope_type == "default": + return URL_DEFAULT_CLIENTSCOPE + if scope_type == "optional": + return URL_OPTIONAL_CLIENTSCOPE + else: + if scope_type == "default": + return URL_CLIENT_DEFAULT_CLIENTSCOPE + if scope_type == "optional": + return URL_CLIENT_OPTIONAL_CLIENTSCOPE + + def add_default_clientscope(self, id, realm="master", client_id=None): + """Add a client scope as default either on realm or client level. + + :param id: Client scope Id. + :param realm: Realm in which the clientscope resides. + :param client_id: The client in which the clientscope resides. + """ + self._action_type_clientscope(id, client_id, "default", realm, 'add') + + def add_optional_clientscope(self, id, realm="master", client_id=None): + """Add a client scope as optional either on realm or client level. + + :param id: Client scope Id. + :param realm: Realm in which the clientscope resides. + :param client_id: The client in which the clientscope resides. + """ + self._action_type_clientscope(id, client_id, "optional", realm, 'add') + + def delete_default_clientscope(self, id, realm="master", client_id=None): + """Remove a client scope as default either on realm or client level. + + :param id: Client scope Id. + :param realm: Realm in which the clientscope resides. + :param client_id: The client in which the clientscope resides. + """ + self._action_type_clientscope(id, client_id, "default", realm, 'delete') + + def delete_optional_clientscope(self, id, realm="master", client_id=None): + """Remove a client scope as optional either on realm or client level. + + :param id: Client scope Id. + :param realm: Realm in which the clientscope resides. + :param client_id: The client in which the clientscope resides. + """ + self._action_type_clientscope(id, client_id, "optional", realm, 'delete') + + def _action_type_clientscope(self, id=None, client_id=None, scope_type="default", realm="master", action='add'): + """ Delete or add a clientscope of type. + :param name: The name of the clientscope. A lookup will be performed to retrieve the clientscope ID. + :param client_id: The ID of the clientscope (preferred to name). + :param scope_type 'default' or 'optional' + :param realm: The realm in which this group resides, default "master". + """ + cid = None if client_id is None else self.get_client_id(client_id=client_id, realm=realm) + # should have a good cid by here. + clientscope_type_url = self._decide_url_type_clientscope(client_id, scope_type).format(realm=realm, id=id, cid=cid, url=self.baseurl) + try: + method = 'PUT' if action == "add" else 'DELETE' + return open_url(clientscope_type_url, method=method, http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + + except Exception as e: + place = 'realm' if client_id is None else 'client ' + client_id + self.fail_open_url(e, msg="Unable to %s %s clientscope %s @ %s : %s" % (action, scope_type, id, place, str(e))) + def create_clientsecret(self, id, realm="master"): """ Generate a new client secret by id @@ -1173,14 +1420,15 @@ class KeycloakAPI(object): 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, + return json.loads(to_native(open_url(clientsecret_url, method='POST', http_agent=self.http_agent, 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' + self.fail_open_url(e, 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' @@ -1196,14 +1444,15 @@ class KeycloakAPI(object): 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, + return json.loads(to_native(open_url(clientsecret_url, method='GET', http_agent=self.http_agent, 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' + self.fail_open_url(e, 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' @@ -1223,7 +1472,7 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except Exception as e: - self.module.fail_json(msg="Could not fetch list of groups in realm %s: %s" + self.fail_open_url(e, msg="Could not fetch list of groups in realm %s: %s" % (realm, str(e))) def get_group_by_groupid(self, gid, realm="master"): @@ -1244,7 +1493,7 @@ class KeycloakAPI(object): if e.code == 404: return None else: - self.module.fail_json(msg="Could not fetch group %s in realm %s: %s" + self.fail_open_url(e, msg="Could not fetch group %s in realm %s: %s" % (gid, realm, str(e))) except Exception as e: self.module.fail_json(msg="Could not fetch group %s in realm %s: %s" @@ -1339,7 +1588,7 @@ class KeycloakAPI(object): def get_subgroup_direct_parent(self, parents, realm="master", children_to_resolve=None): """ Get keycloak direct parent group API object for a given chain of parents. - To succesfully work the API for subgroups we actually dont need + To successfully work the API for subgroups we actually don't need to "walk the whole tree" for nested groups but only need to know the ID for the direct predecessor of current subgroup. This method will guarantee us this information getting there with @@ -1391,7 +1640,7 @@ class KeycloakAPI(object): return open_url(groups_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(grouprep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg="Could not create group %s in realm %s: %s" + self.fail_open_url(e, msg="Could not create group %s in realm %s: %s" % (grouprep['name'], realm, str(e))) def create_subgroup(self, parents, grouprep, realm="master"): @@ -1419,7 +1668,7 @@ class KeycloakAPI(object): return open_url(url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(grouprep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg="Could not create subgroup %s for parent group %s in realm %s: %s" + self.fail_open_url(e, msg="Could not create subgroup %s for parent group %s in realm %s: %s" % (grouprep['name'], parent_id, realm, str(e))) def update_group(self, grouprep, realm="master"): @@ -1434,7 +1683,7 @@ class KeycloakAPI(object): return open_url(group_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(grouprep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not update group %s in realm %s: %s' + self.fail_open_url(e, msg='Could not update group %s in realm %s: %s' % (grouprep['name'], realm, str(e))) def delete_group(self, name=None, groupid=None, realm="master"): @@ -1471,7 +1720,7 @@ class KeycloakAPI(object): return open_url(group_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg="Unable to delete group %s: %s" % (groupid, str(e))) + self.fail_open_url(e, msg="Unable to delete group %s: %s" % (groupid, str(e))) def get_realm_roles(self, realm='master'): """ Obtains role representations for roles in a realm @@ -1488,7 +1737,7 @@ class KeycloakAPI(object): self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of roles for realm %s: %s' % (realm, str(e))) except Exception as e: - self.module.fail_json(msg='Could not obtain list of roles for realm %s: %s' + self.fail_open_url(e, msg='Could not obtain list of roles for realm %s: %s' % (realm, str(e))) def get_realm_role(self, name, realm='master'): @@ -1498,7 +1747,7 @@ class KeycloakAPI(object): :param name: Name of the role to fetch. :param realm: Realm in which the role resides; default 'master'. """ - role_url = URL_REALM_ROLE.format(url=self.baseurl, realm=realm, name=quote(name)) + role_url = URL_REALM_ROLE.format(url=self.baseurl, realm=realm, name=quote(name, safe='')) try: return json.loads(to_native(open_url(role_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) @@ -1506,7 +1755,7 @@ class KeycloakAPI(object): if e.code == 404: return None else: - self.module.fail_json(msg='Could not fetch role %s in realm %s: %s' + self.fail_open_url(e, msg='Could not fetch role %s in realm %s: %s' % (name, realm, str(e))) except Exception as e: self.module.fail_json(msg='Could not fetch role %s in realm %s: %s' @@ -1520,10 +1769,13 @@ class KeycloakAPI(object): """ roles_url = URL_REALM_ROLES.format(url=self.baseurl, realm=realm) try: + if "composites" in rolerep: + keycloak_compatible_composites = self.convert_role_composites(rolerep["composites"]) + rolerep["composites"] = keycloak_compatible_composites return open_url(roles_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(rolerep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not create role %s in realm %s: %s' + self.fail_open_url(e, msg='Could not create role %s in realm %s: %s' % (rolerep['name'], realm, str(e))) def update_realm_role(self, rolerep, realm='master'): @@ -1532,26 +1784,138 @@ class KeycloakAPI(object): :param rolerep: A RoleRepresentation of the updated role. :return HTTPResponse object on success """ - role_url = URL_REALM_ROLE.format(url=self.baseurl, realm=realm, name=quote(rolerep['name'])) + role_url = URL_REALM_ROLE.format(url=self.baseurl, realm=realm, name=quote(rolerep['name']), safe='') try: - return open_url(role_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, - data=json.dumps(rolerep), validate_certs=self.validate_certs) + composites = None + if "composites" in rolerep: + composites = copy.deepcopy(rolerep["composites"]) + del rolerep["composites"] + role_response = open_url(role_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(rolerep), validate_certs=self.validate_certs) + if composites is not None: + self.update_role_composites(rolerep=rolerep, composites=composites, realm=realm) + return role_response except Exception as e: - self.module.fail_json(msg='Could not update role %s in realm %s: %s' + self.fail_open_url(e, msg='Could not update role %s in realm %s: %s' % (rolerep['name'], realm, str(e))) + def get_role_composites(self, rolerep, clientid=None, realm='master'): + composite_url = '' + try: + if clientid is not None: + client = self.get_client_by_clientid(client_id=clientid, realm=realm) + cid = client['id'] + composite_url = URL_CLIENT_ROLE_COMPOSITES.format(url=self.baseurl, realm=realm, id=cid, name=quote(rolerep["name"], safe='')) + else: + composite_url = URL_REALM_ROLE_COMPOSITES.format(url=self.baseurl, realm=realm, name=quote(rolerep["name"], safe='')) + # Get existing composites + return json.loads(to_native(open_url( + composite_url, + method='GET', + http_agent=self.http_agent, + headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.fail_open_url(e, msg='Could not get role %s composites in realm %s: %s' + % (rolerep['name'], realm, str(e))) + + def create_role_composites(self, rolerep, composites, clientid=None, realm='master'): + composite_url = '' + try: + if clientid is not None: + client = self.get_client_by_clientid(client_id=clientid, realm=realm) + cid = client['id'] + composite_url = URL_CLIENT_ROLE_COMPOSITES.format(url=self.baseurl, realm=realm, id=cid, name=quote(rolerep["name"], safe='')) + else: + composite_url = URL_REALM_ROLE_COMPOSITES.format(url=self.baseurl, realm=realm, name=quote(rolerep["name"], safe='')) + # Get existing composites + # create new composites + return open_url(composite_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(composites), validate_certs=self.validate_certs) + except Exception as e: + self.fail_open_url(e, msg='Could not create role %s composites in realm %s: %s' + % (rolerep['name'], realm, str(e))) + + def delete_role_composites(self, rolerep, composites, clientid=None, realm='master'): + composite_url = '' + try: + if clientid is not None: + client = self.get_client_by_clientid(client_id=clientid, realm=realm) + cid = client['id'] + composite_url = URL_CLIENT_ROLE_COMPOSITES.format(url=self.baseurl, realm=realm, id=cid, name=quote(rolerep["name"], safe='')) + else: + composite_url = URL_REALM_ROLE_COMPOSITES.format(url=self.baseurl, realm=realm, name=quote(rolerep["name"], safe='')) + # Get existing composites + # create new composites + return open_url(composite_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(composites), validate_certs=self.validate_certs) + except Exception as e: + self.fail_open_url(e, msg='Could not create role %s composites in realm %s: %s' + % (rolerep['name'], realm, str(e))) + + def update_role_composites(self, rolerep, composites, clientid=None, realm='master'): + # Get existing composites + existing_composites = self.get_role_composites(rolerep=rolerep, clientid=clientid, realm=realm) + composites_to_be_created = [] + composites_to_be_deleted = [] + for composite in composites: + composite_found = False + existing_composite_client = None + for existing_composite in existing_composites: + if existing_composite["clientRole"]: + existing_composite_client = self.get_client_by_id(existing_composite["containerId"], realm=realm) + if ("client_id" in composite + and composite['client_id'] is not None + and existing_composite_client["clientId"] == composite["client_id"] + and composite["name"] == existing_composite["name"]): + composite_found = True + break + else: + if (("client_id" not in composite or composite['client_id'] is None) + and composite["name"] == existing_composite["name"]): + composite_found = True + break + if (not composite_found and ('state' not in composite or composite['state'] == 'present')): + if "client_id" in composite and composite['client_id'] is not None: + client_roles = self.get_client_roles(clientid=composite['client_id'], realm=realm) + for client_role in client_roles: + if client_role['name'] == composite['name']: + composites_to_be_created.append(client_role) + break + else: + realm_role = self.get_realm_role(name=composite["name"], realm=realm) + composites_to_be_created.append(realm_role) + elif composite_found and 'state' in composite and composite['state'] == 'absent': + if "client_id" in composite and composite['client_id'] is not None: + client_roles = self.get_client_roles(clientid=composite['client_id'], realm=realm) + for client_role in client_roles: + if client_role['name'] == composite['name']: + composites_to_be_deleted.append(client_role) + break + else: + realm_role = self.get_realm_role(name=composite["name"], realm=realm) + composites_to_be_deleted.append(realm_role) + + if len(composites_to_be_created) > 0: + # create new composites + self.create_role_composites(rolerep=rolerep, composites=composites_to_be_created, clientid=clientid, realm=realm) + if len(composites_to_be_deleted) > 0: + # delete new composites + self.delete_role_composites(rolerep=rolerep, composites=composites_to_be_deleted, clientid=clientid, realm=realm) + def delete_realm_role(self, name, realm='master'): """ Delete a realm role. :param name: The name of the role. :param realm: The realm in which this role resides, default "master". """ - role_url = URL_REALM_ROLE.format(url=self.baseurl, realm=realm, name=quote(name)) + role_url = URL_REALM_ROLE.format(url=self.baseurl, realm=realm, name=quote(name, safe='')) try: return open_url(role_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Unable to delete role %s in realm %s: %s' + self.fail_open_url(e, msg='Unable to delete role %s in realm %s: %s' % (name, realm, str(e))) def get_client_roles(self, clientid, realm='master'): @@ -1574,7 +1938,7 @@ class KeycloakAPI(object): self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of roles for client %s in realm %s: %s' % (clientid, realm, str(e))) except Exception as e: - self.module.fail_json(msg='Could not obtain list of roles for client %s in realm %s: %s' + self.fail_open_url(e, msg='Could not obtain list of roles for client %s in realm %s: %s' % (clientid, realm, str(e))) def get_client_role(self, name, clientid, realm='master'): @@ -1590,7 +1954,7 @@ class KeycloakAPI(object): if cid is None: self.module.fail_json(msg='Could not find client %s in realm %s' % (clientid, realm)) - role_url = URL_CLIENT_ROLE.format(url=self.baseurl, realm=realm, id=cid, name=quote(name)) + role_url = URL_CLIENT_ROLE.format(url=self.baseurl, realm=realm, id=cid, name=quote(name, safe='')) try: return json.loads(to_native(open_url(role_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) @@ -1598,7 +1962,7 @@ class KeycloakAPI(object): if e.code == 404: return None else: - self.module.fail_json(msg='Could not fetch role %s in client %s of realm %s: %s' + self.fail_open_url(e, msg='Could not fetch role %s in client %s of realm %s: %s' % (name, clientid, realm, str(e))) except Exception as e: self.module.fail_json(msg='Could not fetch role %s for client %s in realm %s: %s' @@ -1618,12 +1982,30 @@ class KeycloakAPI(object): % (clientid, realm)) roles_url = URL_CLIENT_ROLES.format(url=self.baseurl, realm=realm, id=cid) try: + if "composites" in rolerep: + keycloak_compatible_composites = self.convert_role_composites(rolerep["composites"]) + rolerep["composites"] = keycloak_compatible_composites return open_url(roles_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(rolerep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not create role %s for client %s in realm %s: %s' + self.fail_open_url(e, msg='Could not create role %s for client %s in realm %s: %s' % (rolerep['name'], clientid, realm, str(e))) + def convert_role_composites(self, composites): + keycloak_compatible_composites = { + 'client': {}, + 'realm': [] + } + for composite in composites: + if 'state' not in composite or composite['state'] == 'present': + if "client_id" in composite and composite["client_id"] is not None: + if composite["client_id"] not in keycloak_compatible_composites["client"]: + keycloak_compatible_composites["client"][composite["client_id"]] = [] + keycloak_compatible_composites["client"][composite["client_id"]].append(composite["name"]) + else: + keycloak_compatible_composites["realm"].append(composite["name"]) + return keycloak_compatible_composites + def update_client_role(self, rolerep, clientid, realm="master"): """ Update an existing client role. @@ -1636,12 +2018,19 @@ class KeycloakAPI(object): if cid is None: self.module.fail_json(msg='Could not find client %s in realm %s' % (clientid, realm)) - role_url = URL_CLIENT_ROLE.format(url=self.baseurl, realm=realm, id=cid, name=quote(rolerep['name'])) + role_url = URL_CLIENT_ROLE.format(url=self.baseurl, realm=realm, id=cid, name=quote(rolerep['name'], safe='')) try: - return open_url(role_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, - data=json.dumps(rolerep), validate_certs=self.validate_certs) + composites = None + if "composites" in rolerep: + composites = copy.deepcopy(rolerep["composites"]) + del rolerep['composites'] + update_role_response = open_url(role_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(rolerep), validate_certs=self.validate_certs) + if composites is not None: + self.update_role_composites(rolerep=rolerep, clientid=clientid, composites=composites, realm=realm) + return update_role_response except Exception as e: - self.module.fail_json(msg='Could not update role %s for client %s in realm %s: %s' + self.fail_open_url(e, msg='Could not update role %s for client %s in realm %s: %s' % (rolerep['name'], clientid, realm, str(e))) def delete_client_role(self, name, clientid, realm="master"): @@ -1655,12 +2044,12 @@ class KeycloakAPI(object): if cid is None: self.module.fail_json(msg='Could not find client %s in realm %s' % (clientid, realm)) - role_url = URL_CLIENT_ROLE.format(url=self.baseurl, realm=realm, id=cid, name=quote(name)) + role_url = URL_CLIENT_ROLE.format(url=self.baseurl, realm=realm, id=cid, name=quote(name, safe='')) try: return open_url(role_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Unable to delete role %s for client %s in realm %s: %s' + self.fail_open_url(e, msg='Unable to delete role %s for client %s in realm %s: %s' % (name, clientid, realm, str(e))) def get_authentication_flow_by_alias(self, alias, realm='master'): @@ -1682,7 +2071,7 @@ class KeycloakAPI(object): break return authentication_flow except Exception as e: - self.module.fail_json(msg="Unable get authentication flow %s: %s" % (alias, str(e))) + self.fail_open_url(e, msg="Unable get authentication flow %s: %s" % (alias, str(e))) def delete_authentication_flow_by_id(self, id, realm='master'): """ @@ -1697,8 +2086,8 @@ class KeycloakAPI(object): return open_url(flow_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not delete authentication flow %s in realm %s: %s' - % (id, realm, str(e))) + self.fail_open_url(e, msg='Could not delete authentication flow %s in realm %s: %s' + % (id, realm, str(e))) def copy_auth_flow(self, config, realm='master'): """ @@ -1715,7 +2104,7 @@ class KeycloakAPI(object): URL_AUTHENTICATION_FLOW_COPY.format( url=self.baseurl, realm=realm, - copyfrom=quote(config["copyFrom"])), + copyfrom=quote(config["copyFrom"], safe='')), method='POST', http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(new_name), @@ -1734,8 +2123,8 @@ class KeycloakAPI(object): return flow return None except Exception as e: - self.module.fail_json(msg='Could not copy authentication flow %s in realm %s: %s' - % (config["alias"], realm, str(e))) + self.fail_open_url(e, msg='Could not copy authentication flow %s in realm %s: %s' + % (config["alias"], realm, str(e))) def create_empty_auth_flow(self, config, realm='master'): """ @@ -1774,8 +2163,8 @@ class KeycloakAPI(object): return flow return None except Exception as e: - self.module.fail_json(msg='Could not create empty authentication flow %s in realm %s: %s' - % (config["alias"], realm, str(e))) + self.fail_open_url(e, msg='Could not create empty authentication flow %s in realm %s: %s' + % (config["alias"], realm, str(e))) def update_authentication_executions(self, flowAlias, updatedExec, realm='master'): """ Update authentication executions @@ -1789,12 +2178,15 @@ class KeycloakAPI(object): URL_AUTHENTICATION_FLOW_EXECUTIONS.format( url=self.baseurl, realm=realm, - flowalias=quote(flowAlias)), + flowalias=quote(flowAlias, safe='')), method='PUT', http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(updatedExec), timeout=self.connection_timeout, validate_certs=self.validate_certs) + except HTTPError as e: + self.fail_open_url(e, msg="Unable to update execution '%s': %s: %s %s" + % (flowAlias, repr(e), ";".join([e.url, e.msg, str(e.code), str(e.hdrs)]), str(updatedExec))) except Exception as e: self.module.fail_json(msg="Unable to update executions %s: %s" % (updatedExec, str(e))) @@ -1817,9 +2209,9 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg="Unable to add authenticationConfig %s: %s" % (executionId, str(e))) + self.fail_open_url(e, msg="Unable to add authenticationConfig %s: %s" % (executionId, str(e))) - def create_subflow(self, subflowName, flowAlias, realm='master'): + def create_subflow(self, subflowName, flowAlias, realm='master', flowType='basic-flow'): """ Create new sublow on the flow :param subflowName: name of the subflow to create @@ -1830,19 +2222,19 @@ class KeycloakAPI(object): newSubFlow = {} newSubFlow["alias"] = subflowName newSubFlow["provider"] = "registration-page-form" - newSubFlow["type"] = "basic-flow" + newSubFlow["type"] = flowType open_url( URL_AUTHENTICATION_FLOW_EXECUTIONS_FLOW.format( url=self.baseurl, realm=realm, - flowalias=quote(flowAlias)), + flowalias=quote(flowAlias, safe='')), method='POST', http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(newSubFlow), timeout=self.connection_timeout, validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg="Unable to create new subflow %s: %s" % (subflowName, str(e))) + self.fail_open_url(e, msg="Unable to create new subflow %s: %s" % (subflowName, str(e))) def create_execution(self, execution, flowAlias, realm='master'): """ Create new execution on the flow @@ -1859,14 +2251,17 @@ class KeycloakAPI(object): URL_AUTHENTICATION_FLOW_EXECUTIONS_EXECUTION.format( url=self.baseurl, realm=realm, - flowalias=quote(flowAlias)), + flowalias=quote(flowAlias, safe='')), method='POST', http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(newExec), timeout=self.connection_timeout, validate_certs=self.validate_certs) + except HTTPError as e: + self.fail_open_url(e, msg="Unable to create new execution '%s' %s: %s: %s %s" + % (flowAlias, execution["providerId"], repr(e), ";".join([e.url, e.msg, str(e.code), str(e.hdrs)]), str(newExec))) except Exception as e: - self.module.fail_json(msg="Unable to create new execution %s: %s" % (execution["provider"], str(e))) + self.module.fail_json(msg="Unable to create new execution '%s' %s: %s" % (flowAlias, execution["providerId"], repr(e))) def change_execution_priority(self, executionId, diff, realm='master'): """ Raise or lower execution priority of diff time @@ -1900,7 +2295,7 @@ class KeycloakAPI(object): timeout=self.connection_timeout, validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg="Unable to change execution priority %s: %s" % (executionId, str(e))) + self.fail_open_url(e, msg="Unable to change execution priority %s: %s" % (executionId, str(e))) def get_executions_representation(self, config, realm='master'): """ @@ -1916,7 +2311,7 @@ class KeycloakAPI(object): URL_AUTHENTICATION_FLOW_EXECUTIONS.format( url=self.baseurl, realm=realm, - flowalias=quote(config["alias"])), + flowalias=quote(config["alias"], safe='')), method='GET', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, @@ -1937,8 +2332,121 @@ class KeycloakAPI(object): execution["authenticationConfig"] = execConfig return executions except Exception as e: - self.module.fail_json(msg='Could not get executions for authentication flow %s in realm %s: %s' - % (config["alias"], realm, str(e))) + self.fail_open_url(e, msg='Could not get executions for authentication flow %s in realm %s: %s' + % (config["alias"], realm, str(e))) + + def get_required_actions(self, realm='master'): + """ + Get required actions. + :param realm: Realm name (not id). + :return: List of representations of the required actions. + """ + + try: + required_actions = json.load( + open_url( + URL_AUTHENTICATION_REQUIRED_ACTIONS.format( + url=self.baseurl, + realm=realm + ), + method='GET', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs + ) + ) + + return required_actions + except Exception: + return None + + def register_required_action(self, rep, realm='master'): + """ + Register required action. + :param rep: JSON containing 'providerId', and 'name' attributes. + :param realm: Realm name (not id). + :return: Representation of the required action. + """ + + data = { + 'name': rep['name'], + 'providerId': rep['providerId'] + } + + try: + return open_url( + URL_AUTHENTICATION_REGISTER_REQUIRED_ACTION.format( + url=self.baseurl, + realm=realm + ), + method='POST', + http_agent=self.http_agent, headers=self.restheaders, + data=json.dumps(data), + timeout=self.connection_timeout, + validate_certs=self.validate_certs + ) + except Exception as e: + self.fail_open_url( + e, + msg='Unable to register required action %s in realm %s: %s' + % (rep["name"], realm, str(e)) + ) + + def update_required_action(self, alias, rep, realm='master'): + """ + Update required action. + :param alias: Alias of required action. + :param rep: JSON describing new state of required action. + :param realm: Realm name (not id). + :return: HTTPResponse object on success. + """ + + try: + return open_url( + URL_AUTHENTICATION_REQUIRED_ACTIONS_ALIAS.format( + url=self.baseurl, + alias=quote(alias, safe=''), + realm=realm + ), + method='PUT', + http_agent=self.http_agent, headers=self.restheaders, + data=json.dumps(rep), + timeout=self.connection_timeout, + validate_certs=self.validate_certs + ) + except Exception as e: + self.fail_open_url( + e, + msg='Unable to update required action %s in realm %s: %s' + % (alias, realm, str(e)) + ) + + def delete_required_action(self, alias, realm='master'): + """ + Delete required action. + :param alias: Alias of required action. + :param realm: Realm name (not id). + :return: HTTPResponse object on success. + """ + + try: + return open_url( + URL_AUTHENTICATION_REQUIRED_ACTIONS_ALIAS.format( + url=self.baseurl, + alias=quote(alias, safe=''), + realm=realm + ), + method='DELETE', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs + ) + except Exception as e: + self.fail_open_url( + e, + msg='Unable to delete required action %s in realm %s: %s' + % (alias, realm, str(e)) + ) def get_identity_providers(self, realm='master'): """ Fetch representations for identity providers in a realm @@ -1953,7 +2461,7 @@ class KeycloakAPI(object): self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of identity providers for realm %s: %s' % (realm, str(e))) except Exception as e: - self.module.fail_json(msg='Could not obtain list of identity providers for realm %s: %s' + self.fail_open_url(e, msg='Could not obtain list of identity providers for realm %s: %s' % (realm, str(e))) def get_identity_provider(self, alias, realm='master'): @@ -1970,7 +2478,7 @@ class KeycloakAPI(object): if e.code == 404: return None else: - self.module.fail_json(msg='Could not fetch identity provider %s in realm %s: %s' + self.fail_open_url(e, msg='Could not fetch identity provider %s in realm %s: %s' % (alias, realm, str(e))) except Exception as e: self.module.fail_json(msg='Could not fetch identity provider %s in realm %s: %s' @@ -1987,7 +2495,7 @@ class KeycloakAPI(object): return open_url(idps_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(idprep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not create identity provider %s in realm %s: %s' + self.fail_open_url(e, msg='Could not create identity provider %s in realm %s: %s' % (idprep['alias'], realm, str(e))) def update_identity_provider(self, idprep, realm='master'): @@ -2001,7 +2509,7 @@ class KeycloakAPI(object): return open_url(idp_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(idprep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not update identity provider %s in realm %s: %s' + self.fail_open_url(e, msg='Could not update identity provider %s in realm %s: %s' % (idprep['alias'], realm, str(e))) def delete_identity_provider(self, alias, realm='master'): @@ -2014,7 +2522,7 @@ class KeycloakAPI(object): return open_url(idp_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Unable to delete identity provider %s in realm %s: %s' + self.fail_open_url(e, msg='Unable to delete identity provider %s in realm %s: %s' % (alias, realm, str(e))) def get_identity_provider_mappers(self, alias, realm='master'): @@ -2032,7 +2540,7 @@ class KeycloakAPI(object): self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of identity provider mappers for idp %s in realm %s: %s' % (alias, realm, str(e))) except Exception as e: - self.module.fail_json(msg='Could not obtain list of identity provider mappers for idp %s in realm %s: %s' + self.fail_open_url(e, msg='Could not obtain list of identity provider mappers for idp %s in realm %s: %s' % (alias, realm, str(e))) def get_identity_provider_mapper(self, mid, alias, realm='master'): @@ -2051,7 +2559,7 @@ class KeycloakAPI(object): if e.code == 404: return None else: - self.module.fail_json(msg='Could not fetch mapper %s for identity provider %s in realm %s: %s' + self.fail_open_url(e, msg='Could not fetch mapper %s for identity provider %s in realm %s: %s' % (mid, alias, realm, str(e))) except Exception as e: self.module.fail_json(msg='Could not fetch mapper %s for identity provider %s in realm %s: %s' @@ -2069,7 +2577,7 @@ class KeycloakAPI(object): return open_url(mappers_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(mapper), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not create identity provider mapper %s for idp %s in realm %s: %s' + self.fail_open_url(e, msg='Could not create identity provider mapper %s for idp %s in realm %s: %s' % (mapper['name'], alias, realm, str(e))) def update_identity_provider_mapper(self, mapper, alias, realm='master'): @@ -2084,7 +2592,7 @@ class KeycloakAPI(object): return open_url(mapper_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(mapper), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not update mapper %s for identity provider %s in realm %s: %s' + self.fail_open_url(e, msg='Could not update mapper %s for identity provider %s in realm %s: %s' % (mapper['id'], alias, realm, str(e))) def delete_identity_provider_mapper(self, mid, alias, realm='master'): @@ -2098,7 +2606,7 @@ class KeycloakAPI(object): return open_url(mapper_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Unable to delete mapper %s for identity provider %s in realm %s: %s' + self.fail_open_url(e, msg='Unable to delete mapper %s for identity provider %s in realm %s: %s' % (mid, alias, realm, str(e))) def get_components(self, filter=None, realm='master'): @@ -2118,7 +2626,7 @@ class KeycloakAPI(object): self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of components for realm %s: %s' % (realm, str(e))) except Exception as e: - self.module.fail_json(msg='Could not obtain list of components for realm %s: %s' + self.fail_open_url(e, msg='Could not obtain list of components for realm %s: %s' % (realm, str(e))) def get_component(self, cid, realm='master'): @@ -2135,7 +2643,7 @@ class KeycloakAPI(object): if e.code == 404: return None else: - self.module.fail_json(msg='Could not fetch component %s in realm %s: %s' + self.fail_open_url(e, msg='Could not fetch component %s in realm %s: %s' % (cid, realm, str(e))) except Exception as e: self.module.fail_json(msg='Could not fetch component %s in realm %s: %s' @@ -2158,7 +2666,7 @@ class KeycloakAPI(object): return json.loads(to_native(open_url(comp_url, method="GET", http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs).read())) except Exception as e: - self.module.fail_json(msg='Could not create component in realm %s: %s' + self.fail_open_url(e, msg='Could not create component in realm %s: %s' % (realm, str(e))) def update_component(self, comprep, realm='master'): @@ -2175,7 +2683,7 @@ class KeycloakAPI(object): return open_url(comp_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, data=json.dumps(comprep), validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Could not update component %s in realm %s: %s' + self.fail_open_url(e, msg='Could not update component %s in realm %s: %s' % (cid, realm, str(e))) def delete_component(self, cid, realm='master'): @@ -2188,5 +2696,496 @@ class KeycloakAPI(object): return open_url(comp_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs) except Exception as e: - self.module.fail_json(msg='Unable to delete component %s in realm %s: %s' + self.fail_open_url(e, msg='Unable to delete component %s in realm %s: %s' % (cid, realm, str(e))) + + def get_authz_authorization_scope_by_name(self, name, client_id, realm): + url = URL_AUTHZ_AUTHORIZATION_SCOPES.format(url=self.baseurl, client_id=client_id, realm=realm) + search_url = "%s/search?name=%s" % (url, quote(name, safe='')) + + try: + return json.loads(to_native(open_url(search_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception: + return False + + def create_authz_authorization_scope(self, payload, client_id, realm): + """Create an authorization scope for a Keycloak client""" + url = URL_AUTHZ_AUTHORIZATION_SCOPES.format(url=self.baseurl, client_id=client_id, realm=realm) + + try: + return open_url(url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + except Exception as e: + self.fail_open_url(e, msg='Could not create authorization scope %s for client %s in realm %s: %s' % (payload['name'], client_id, realm, str(e))) + + def update_authz_authorization_scope(self, payload, id, client_id, realm): + """Update an authorization scope for a Keycloak client""" + url = URL_AUTHZ_AUTHORIZATION_SCOPE.format(url=self.baseurl, id=id, client_id=client_id, realm=realm) + + try: + return open_url(url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + except Exception as e: + self.fail_open_url(e, msg='Could not create update scope %s for client %s in realm %s: %s' % (payload['name'], client_id, realm, str(e))) + + def remove_authz_authorization_scope(self, id, client_id, realm): + """Remove an authorization scope from a Keycloak client""" + url = URL_AUTHZ_AUTHORIZATION_SCOPE.format(url=self.baseurl, id=id, client_id=client_id, realm=realm) + + try: + return open_url(url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.fail_open_url(e, msg='Could not delete scope %s for client %s in realm %s: %s' % (id, client_id, realm, str(e))) + + def get_user_by_id(self, user_id, realm='master'): + """ + Get a User by its ID. + :param user_id: ID of the user. + :param realm: Realm + :return: Representation of the user. + """ + try: + user_url = URL_USER.format( + url=self.baseurl, + realm=realm, + id=user_id) + userrep = json.load( + open_url( + user_url, + method='GET', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs)) + return userrep + except Exception as e: + self.fail_open_url(e, msg='Could not get user %s in realm %s: %s' + % (user_id, realm, str(e))) + + def create_user(self, userrep, realm='master'): + """ + Create a new User. + :param userrep: Representation of the user to create + :param realm: Realm + :return: Representation of the user created. + """ + try: + if 'attributes' in userrep and isinstance(userrep['attributes'], list): + attributes = copy.deepcopy(userrep['attributes']) + userrep['attributes'] = self.convert_user_attributes_to_keycloak_dict(attributes=attributes) + users_url = URL_USERS.format( + url=self.baseurl, + realm=realm) + open_url(users_url, + method='POST', + http_agent=self.http_agent, headers=self.restheaders, + data=json.dumps(userrep), + timeout=self.connection_timeout, + validate_certs=self.validate_certs) + created_user = self.get_user_by_username( + username=userrep['username'], + realm=realm) + return created_user + except Exception as e: + self.fail_open_url(e, msg='Could not create user %s in realm %s: %s' + % (userrep['username'], realm, str(e))) + + def convert_user_attributes_to_keycloak_dict(self, attributes): + keycloak_user_attributes_dict = {} + for attribute in attributes: + if ('state' not in attribute or attribute['state'] == 'present') and 'name' in attribute: + keycloak_user_attributes_dict[attribute['name']] = attribute['values'] if 'values' in attribute else [] + return keycloak_user_attributes_dict + + def convert_keycloak_user_attributes_dict_to_module_list(self, attributes): + module_attributes_list = [] + for key in attributes: + attr = {} + attr['name'] = key + attr['values'] = attributes[key] + module_attributes_list.append(attr) + return module_attributes_list + + def update_user(self, userrep, realm='master'): + """ + Update a User. + :param userrep: Representation of the user to update. This representation must include the ID of the user. + :param realm: Realm + :return: Representation of the updated user. + """ + try: + if 'attributes' in userrep and isinstance(userrep['attributes'], list): + attributes = copy.deepcopy(userrep['attributes']) + userrep['attributes'] = self.convert_user_attributes_to_keycloak_dict(attributes=attributes) + user_url = URL_USER.format( + url=self.baseurl, + realm=realm, + id=userrep["id"]) + open_url( + user_url, + method='PUT', + http_agent=self.http_agent, headers=self.restheaders, + data=json.dumps(userrep), + timeout=self.connection_timeout, + validate_certs=self.validate_certs) + updated_user = self.get_user_by_id( + user_id=userrep['id'], + realm=realm) + return updated_user + except Exception as e: + self.fail_open_url(e, msg='Could not update user %s in realm %s: %s' + % (userrep['username'], realm, str(e))) + + def delete_user(self, user_id, realm='master'): + """ + Delete a User. + :param user_id: ID of the user to be deleted + :param realm: Realm + :return: HTTP response. + """ + try: + user_url = URL_USER.format( + url=self.baseurl, + realm=realm, + id=user_id) + return open_url( + user_url, + method='DELETE', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.fail_open_url(e, msg='Could not delete user %s in realm %s: %s' + % (user_id, realm, str(e))) + + def get_user_groups(self, user_id, realm='master'): + """ + Get groups for a user. + :param user_id: User ID + :param realm: Realm + :return: Representation of the client groups. + """ + try: + groups = [] + user_groups_url = URL_USER_GROUPS.format( + url=self.baseurl, + realm=realm, + id=user_id) + user_groups = json.load( + open_url( + user_groups_url, + method='GET', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs)) + for user_group in user_groups: + groups.append(user_group["name"]) + return groups + except Exception as e: + self.fail_open_url(e, msg='Could not get groups for user %s in realm %s: %s' + % (user_id, realm, str(e))) + + def add_user_in_group(self, user_id, group_id, realm='master'): + """ + Add a user to a group. + :param user_id: User ID + :param group_id: Group Id to add the user to. + :param realm: Realm + :return: HTTP Response + """ + try: + user_group_url = URL_USER_GROUP.format( + url=self.baseurl, + realm=realm, + id=user_id, + group_id=group_id) + return open_url( + user_group_url, + method='PUT', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.fail_open_url(e, msg='Could not add user %s in group %s in realm %s: %s' + % (user_id, group_id, realm, str(e))) + + def remove_user_from_group(self, user_id, group_id, realm='master'): + """ + Remove a user from a group for a user. + :param user_id: User ID + :param group_id: Group Id to add the user to. + :param realm: Realm + :return: HTTP response + """ + try: + user_group_url = URL_USER_GROUP.format( + url=self.baseurl, + realm=realm, + id=user_id, + group_id=group_id) + return open_url( + user_group_url, + method='DELETE', + http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.fail_open_url(e, msg='Could not remove user %s from group %s in realm %s: %s' + % (user_id, group_id, realm, str(e))) + + def update_user_groups_membership(self, userrep, groups, realm='master'): + """ + Update user's group membership + :param userrep: Representation of the user. This representation must include the ID. + :param realm: Realm + :return: True if group membership has been changed. False Otherwise. + """ + changed = False + try: + user_existing_groups = self.get_user_groups( + user_id=userrep['id'], + realm=realm) + groups_to_add_and_remove = self.extract_groups_to_add_to_and_remove_from_user(groups) + # If group membership need to be changed + if not is_struct_included(groups_to_add_and_remove['add'], user_existing_groups): + # Get available groups in the realm + realm_groups = self.get_groups(realm=realm) + for realm_group in realm_groups: + if "name" in realm_group and realm_group["name"] in groups_to_add_and_remove['add']: + self.add_user_in_group( + user_id=userrep["id"], + group_id=realm_group["id"], + realm=realm) + changed = True + elif "name" in realm_group and realm_group['name'] in groups_to_add_and_remove['remove']: + self.remove_user_from_group( + user_id=userrep['id'], + group_id=realm_group['id'], + realm=realm) + changed = True + return changed + except Exception as e: + self.module.fail_json(msg='Could not update group membership for user %s in realm %s: %s' + % (userrep['id]'], realm, str(e))) + + def extract_groups_to_add_to_and_remove_from_user(self, groups): + groups_extract = {} + groups_to_add = [] + groups_to_remove = [] + if isinstance(groups, list) and len(groups) > 0: + for group in groups: + group_name = group['name'] if isinstance(group, dict) and 'name' in group else group + if isinstance(group, dict) and ('state' not in group or group['state'] == 'present'): + groups_to_add.append(group_name) + else: + groups_to_remove.append(group_name) + groups_extract['add'] = groups_to_add + groups_extract['remove'] = groups_to_remove + + return groups_extract + + def convert_user_group_list_of_str_to_list_of_dict(self, groups): + list_of_groups = [] + if isinstance(groups, list) and len(groups) > 0: + for group in groups: + if isinstance(group, str): + group_dict = {} + group_dict['name'] = group + list_of_groups.append(group_dict) + return list_of_groups + + def create_authz_custom_policy(self, policy_type, payload, client_id, realm): + """Create a custom policy for a Keycloak client""" + url = URL_AUTHZ_CUSTOM_POLICY.format(url=self.baseurl, policy_type=policy_type, client_id=client_id, realm=realm) + + try: + return open_url(url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + except Exception as e: + self.fail_open_url(e, msg='Could not create permission %s for client %s in realm %s: %s' % (payload['name'], client_id, realm, str(e))) + + def remove_authz_custom_policy(self, policy_id, client_id, realm): + """Remove a custom policy from a Keycloak client""" + url = URL_AUTHZ_CUSTOM_POLICIES.format(url=self.baseurl, client_id=client_id, realm=realm) + delete_url = "%s/%s" % (url, policy_id) + + try: + return open_url(delete_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.fail_open_url(e, msg='Could not delete custom policy %s for client %s in realm %s: %s' % (id, client_id, realm, str(e))) + + def get_authz_permission_by_name(self, name, client_id, realm): + """Get authorization permission by name""" + url = URL_AUTHZ_POLICIES.format(url=self.baseurl, client_id=client_id, realm=realm) + search_url = "%s/search?name=%s" % (url, name.replace(' ', '%20')) + + try: + return json.loads(to_native(open_url(search_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception: + return False + + def create_authz_permission(self, payload, permission_type, client_id, realm): + """Create an authorization permission for a Keycloak client""" + url = URL_AUTHZ_PERMISSIONS.format(url=self.baseurl, permission_type=permission_type, client_id=client_id, realm=realm) + + try: + return open_url(url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + except Exception as e: + self.fail_open_url(e, msg='Could not create permission %s for client %s in realm %s: %s' % (payload['name'], client_id, realm, str(e))) + + def remove_authz_permission(self, id, client_id, realm): + """Create an authorization permission for a Keycloak client""" + url = URL_AUTHZ_POLICY.format(url=self.baseurl, id=id, client_id=client_id, realm=realm) + + try: + return open_url(url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs) + except Exception as e: + self.fail_open_url(e, msg='Could not delete permission %s for client %s in realm %s: %s' % (id, client_id, realm, str(e))) + + def update_authz_permission(self, payload, permission_type, id, client_id, realm): + """Update a permission for a Keycloak client""" + url = URL_AUTHZ_PERMISSION.format(url=self.baseurl, permission_type=permission_type, id=id, client_id=client_id, realm=realm) + + try: + return open_url(url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + except Exception as e: + self.fail_open_url(e, msg='Could not create update permission %s for client %s in realm %s: %s' % (payload['name'], client_id, realm, str(e))) + + def get_authz_resource_by_name(self, name, client_id, realm): + """Get authorization resource by name""" + url = URL_AUTHZ_RESOURCES.format(url=self.baseurl, client_id=client_id, realm=realm) + search_url = "%s/search?name=%s" % (url, name.replace(' ', '%20')) + + try: + return json.loads(to_native(open_url(search_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception: + return False + + def get_authz_policy_by_name(self, name, client_id, realm): + """Get authorization policy by name""" + url = URL_AUTHZ_POLICIES.format(url=self.baseurl, client_id=client_id, realm=realm) + search_url = "%s/search?name=%s&permission=false" % (url, name.replace(' ', '%20')) + + try: + return json.loads(to_native(open_url(search_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception: + return False + + def get_client_role_scope_from_client(self, clientid, clientscopeid, realm="master"): + """ Fetch the roles associated with the client's scope for a specific client on the Keycloak server. + :param clientid: ID of the client from which to obtain the associated roles. + :param clientscopeid: ID of the client who owns the roles. + :param realm: Realm from which to obtain the scope. + :return: The client scope of roles from specified client. + """ + client_role_scope_url = URL_CLIENT_ROLE_SCOPE_CLIENTS.format(url=self.baseurl, realm=realm, id=clientid, scopeid=clientscopeid) + try: + return json.loads(to_native(open_url(client_role_scope_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.fail_open_url(e, msg='Could not fetch roles scope for client %s in realm %s: %s' % (clientid, realm, str(e))) + + def update_client_role_scope_from_client(self, payload, clientid, clientscopeid, realm="master"): + """ Update and fetch the roles associated with the client's scope on the Keycloak server. + :param payload: List of roles to be added to the scope. + :param clientid: ID of the client to update scope. + :param clientscopeid: ID of the client who owns the roles. + :param realm: Realm from which to obtain the clients. + :return: The client scope of roles from specified client. + """ + client_role_scope_url = URL_CLIENT_ROLE_SCOPE_CLIENTS.format(url=self.baseurl, realm=realm, id=clientid, scopeid=clientscopeid) + try: + open_url(client_role_scope_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + + except Exception as e: + self.fail_open_url(e, msg='Could not update roles scope for client %s in realm %s: %s' % (clientid, realm, str(e))) + + return self.get_client_role_scope_from_client(clientid, clientscopeid, realm) + + def delete_client_role_scope_from_client(self, payload, clientid, clientscopeid, realm="master"): + """ Delete the roles contains in the payload from the client's scope on the Keycloak server. + :param payload: List of roles to be deleted. + :param clientid: ID of the client to delete roles from scope. + :param clientscopeid: ID of the client who owns the roles. + :param realm: Realm from which to obtain the clients. + :return: The client scope of roles from specified client. + """ + client_role_scope_url = URL_CLIENT_ROLE_SCOPE_CLIENTS.format(url=self.baseurl, realm=realm, id=clientid, scopeid=clientscopeid) + try: + open_url(client_role_scope_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + + except Exception as e: + self.fail_open_url(e, msg='Could not delete roles scope for client %s in realm %s: %s' % (clientid, realm, str(e))) + + return self.get_client_role_scope_from_client(clientid, clientscopeid, realm) + + def get_client_role_scope_from_realm(self, clientid, realm="master"): + """ Fetch the realm roles from the client's scope on the Keycloak server. + :param clientid: ID of the client from which to obtain the associated realm roles. + :param realm: Realm from which to obtain the clients. + :return: The client realm roles scope. + """ + client_role_scope_url = URL_CLIENT_ROLE_SCOPE_REALM.format(url=self.baseurl, realm=realm, id=clientid) + try: + return json.loads(to_native(open_url(client_role_scope_url, method='GET', http_agent=self.http_agent, headers=self.restheaders, + timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + except Exception as e: + self.fail_open_url(e, msg='Could not fetch roles scope for client %s in realm %s: %s' % (clientid, realm, str(e))) + + def update_client_role_scope_from_realm(self, payload, clientid, realm="master"): + """ Update and fetch the realm roles from the client's scope on the Keycloak server. + :param payload: List of realm roles to add. + :param clientid: ID of the client to update scope. + :param realm: Realm from which to obtain the clients. + :return: The client realm roles scope. + """ + client_role_scope_url = URL_CLIENT_ROLE_SCOPE_REALM.format(url=self.baseurl, realm=realm, id=clientid) + try: + open_url(client_role_scope_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + + except Exception as e: + self.fail_open_url(e, msg='Could not update roles scope for client %s in realm %s: %s' % (clientid, realm, str(e))) + + return self.get_client_role_scope_from_realm(clientid, realm) + + def delete_client_role_scope_from_realm(self, payload, clientid, realm="master"): + """ Delete the realm roles contains in the payload from the client's scope on the Keycloak server. + :param payload: List of realm roles to delete. + :param clientid: ID of the client to delete roles from scope. + :param realm: Realm from which to obtain the clients. + :return: The client realm roles scope. + """ + client_role_scope_url = URL_CLIENT_ROLE_SCOPE_REALM.format(url=self.baseurl, realm=realm, id=clientid) + try: + open_url(client_role_scope_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout, + data=json.dumps(payload), validate_certs=self.validate_certs) + + except Exception as e: + self.fail_open_url(e, msg='Could not delete roles scope for client %s in realm %s: %s' % (clientid, realm, str(e))) + + return self.get_client_role_scope_from_realm(clientid, realm) + + def fail_open_url(self, e, msg, **kwargs): + try: + if isinstance(e, HTTPError): + msg = "%s: %s" % (msg, to_native(e.read())) + except Exception as ingore: + pass + self.module.fail_json(msg, **kwargs) diff --git a/plugins/modules/keycloak_client.py b/plugins/modules/keycloak_client.py index dc824ca..0afa52b 100644 --- a/plugins/modules/keycloak_client.py +++ b/plugins/modules/keycloak_client.py @@ -40,8 +40,8 @@ options: state: description: - State of the client - - On C(present), the client will be created (or updated if it exists already). - - On C(absent), the client will be removed if it exists + - On V(present), the client will be created (or updated if it exists already). + - On V(absent), the client will be removed if it exists choices: ['present', 'absent'] default: 'present' type: str @@ -55,7 +55,7 @@ options: client_id: description: - Client id of client to be worked on. This is usually an alphanumeric name chosen by - you. Either this or I(id) is required. If you specify both, I(id) takes precedence. + you. Either this or O(id) is required. If you specify both, O(id) takes precedence. This is 'clientId' in the Keycloak REST API. aliases: - clientId @@ -63,13 +63,13 @@ options: id: description: - - Id of client to be worked on. This is usually an UUID. Either this or I(client_id) + - Id of client to be worked on. This is usually an UUID. Either this or O(client_id) is required. If you specify both, this takes precedence. type: str name: description: - - Name of the client (this is not the same as I(client_id)). + - Name of the client (this is not the same as O(client_id)). type: str description: @@ -108,20 +108,21 @@ options: client_authenticator_type: description: - - How do clients authenticate with the auth server? Either C(client-secret) or - C(client-jwt) can be chosen. When using C(client-secret), the module parameter - I(secret) can set it, while for C(client-jwt), you can use the keys C(use.jwks.url), - C(jwks.url), and C(jwt.credential.certificate) in the I(attributes) module parameter - to configure its behavior. - This is 'clientAuthenticatorType' in the Keycloak REST API. - choices: ['client-secret', 'client-jwt'] + - How do clients authenticate with the auth server? Either V(client-secret), + V(client-jwt), or V(client-x509) can be chosen. When using V(client-secret), the module parameter + O(secret) can set it, for V(client-jwt), you can use the keys C(use.jwks.url), + C(jwks.url), and C(jwt.credential.certificate) in the O(attributes) module parameter + to configure its behavior. For V(client-x509) you can use the keys C(x509.allow.regex.pattern.comparison) + and C(x509.subjectdn) in the O(attributes) module parameter to configure which certificate(s) to accept. + - This is 'clientAuthenticatorType' in the Keycloak REST API. + choices: ['client-secret', 'client-jwt', 'client-x509'] aliases: - clientAuthenticatorType type: str secret: description: - - When using I(client_authenticator_type) C(client-secret) (the default), you can + - When using O(client_authenticator_type=client-secret) (the default), you can specify a secret here (otherwise one will be generated if it does not exit). If changing this secret, the module will not register a change currently (but the changed secret will be saved). @@ -246,9 +247,11 @@ options: protocol: description: - - Type of client (either C(openid-connect) or C(saml). + - Type of client. + - At creation only, default value will be V(openid-connect) if O(protocol) is omitted. + - The V(docker-v2) value was added in community.general 8.6.0. type: str - choices: ['openid-connect', 'saml'] + choices: ['openid-connect', 'saml', 'docker-v2'] full_scope_allowed: description: @@ -286,7 +289,7 @@ options: use_template_config: description: - - Whether or not to use configuration from the I(client_template). + - Whether or not to use configuration from the O(client_template). This is 'useTemplateConfig' in the Keycloak REST API. aliases: - useTemplateConfig @@ -294,7 +297,7 @@ options: use_template_scope: description: - - Whether or not to use scope configuration from the I(client_template). + - Whether or not to use scope configuration from the O(client_template). This is 'useTemplateScope' in the Keycloak REST API. aliases: - useTemplateScope @@ -302,7 +305,7 @@ options: use_template_mappers: description: - - Whether or not to use mapper configuration from the I(client_template). + - Whether or not to use mapper configuration from the O(client_template). This is 'useTemplateMappers' in the Keycloak REST API. aliases: - useTemplateMappers @@ -338,6 +341,42 @@ options: description: - Override realm authentication flow bindings. type: dict + suboptions: + browser: + description: + - Flow ID of the browser authentication flow. + - O(authentication_flow_binding_overrides.browser) + and O(authentication_flow_binding_overrides.browser_name) are mutually exclusive. + type: str + + browser_name: + description: + - Flow name of the browser authentication flow. + - O(authentication_flow_binding_overrides.browser) + and O(authentication_flow_binding_overrides.browser_name) are mutually exclusive. + aliases: + - browserName + type: str + version_added: 9.1.0 + + direct_grant: + description: + - Flow ID of the direct grant authentication flow. + - O(authentication_flow_binding_overrides.direct_grant) + and O(authentication_flow_binding_overrides.direct_grant_name) are mutually exclusive. + aliases: + - directGrant + type: str + + direct_grant_name: + description: + - Flow name of the direct grant authentication flow. + - O(authentication_flow_binding_overrides.direct_grant) + and O(authentication_flow_binding_overrides.direct_grant_name) are mutually exclusive. + aliases: + - directGrantName + type: str + version_added: 9.1.0 aliases: - authenticationFlowBindingOverrides version_added: 3.4.0 @@ -391,38 +430,37 @@ options: protocol: description: - - This is either C(openid-connect) or C(saml), this specifies for which protocol this protocol mapper. - is active. - choices: ['openid-connect', 'saml'] + - This specifies for which protocol this protocol mapper is active. + choices: ['openid-connect', 'saml', 'docker-v2'] type: str protocolMapper: description: - - The Keycloak-internal name of the type of this protocol-mapper. While an exhaustive list is + - "The Keycloak-internal name of the type of this protocol-mapper. While an exhaustive list is impossible to provide since this may be extended through SPIs by the user of Keycloak, - by default Keycloak as of 3.4 ships with at least - - C(docker-v2-allow-all-mapper) - - C(oidc-address-mapper) - - C(oidc-full-name-mapper) - - C(oidc-group-membership-mapper) - - C(oidc-hardcoded-claim-mapper) - - C(oidc-hardcoded-role-mapper) - - C(oidc-role-name-mapper) - - C(oidc-script-based-protocol-mapper) - - C(oidc-sha256-pairwise-sub-mapper) - - C(oidc-usermodel-attribute-mapper) - - C(oidc-usermodel-client-role-mapper) - - C(oidc-usermodel-property-mapper) - - C(oidc-usermodel-realm-role-mapper) - - C(oidc-usersessionmodel-note-mapper) - - C(saml-group-membership-mapper) - - C(saml-hardcode-attribute-mapper) - - C(saml-hardcode-role-mapper) - - C(saml-role-list-mapper) - - C(saml-role-name-mapper) - - C(saml-user-attribute-mapper) - - C(saml-user-property-mapper) - - C(saml-user-session-note-mapper) + by default Keycloak as of 3.4 ships with at least:" + - V(docker-v2-allow-all-mapper) + - V(oidc-address-mapper) + - V(oidc-full-name-mapper) + - V(oidc-group-membership-mapper) + - V(oidc-hardcoded-claim-mapper) + - V(oidc-hardcoded-role-mapper) + - V(oidc-role-name-mapper) + - V(oidc-script-based-protocol-mapper) + - V(oidc-sha256-pairwise-sub-mapper) + - V(oidc-usermodel-attribute-mapper) + - V(oidc-usermodel-client-role-mapper) + - V(oidc-usermodel-property-mapper) + - V(oidc-usermodel-realm-role-mapper) + - V(oidc-usersessionmodel-note-mapper) + - V(saml-group-membership-mapper) + - V(saml-hardcode-attribute-mapper) + - V(saml-hardcode-role-mapper) + - V(saml-role-list-mapper) + - V(saml-role-name-mapper) + - V(saml-user-attribute-mapper) + - V(saml-user-property-mapper) + - V(saml-user-session-note-mapper) - An exhaustive list of available mappers on your installation can be obtained on the admin console by going to Server Info -> Providers and looking under 'protocol-mapper'. @@ -431,10 +469,10 @@ options: config: description: - Dict specifying the configuration options for the protocol mapper; the - contents differ depending on the value of I(protocolMapper) and are not documented + contents differ depending on the value of O(protocol_mappers[].protocolMapper) and are not documented other than by the source of the mappers and its parent class(es). An example is given below. It is easiest to obtain valid config values by dumping an already-existing - protocol mapper configuration through check-mode in the I(existing) field. + protocol mapper configuration through check-mode in the RV(existing) field. type: dict attributes: @@ -478,7 +516,7 @@ options: saml.signature.algorithm: description: - - Signature algorithm used to sign SAML documents. One of C(RSA_SHA256), C(RSA_SHA1), C(RSA_SHA512), or C(DSA_SHA1). + - Signature algorithm used to sign SAML documents. One of V(RSA_SHA256), V(RSA_SHA1), V(RSA_SHA512), or V(DSA_SHA1). saml.signing.certificate: description: @@ -496,22 +534,21 @@ options: description: - SAML Redirect Binding URL for the client's assertion consumer service (login responses). - saml_force_name_id_format: description: - For SAML clients, Boolean specifying whether to ignore requested NameID subject format and using the configured one instead. saml_name_id_format: description: - - For SAML clients, the NameID format to use (one of C(username), C(email), C(transient), or C(persistent)) + - For SAML clients, the NameID format to use (one of V(username), V(email), V(transient), or V(persistent)) saml_signature_canonicalization_method: description: - SAML signature canonicalization method. This is one of four values, namely - C(http://www.w3.org/2001/10/xml-exc-c14n#) for EXCLUSIVE, - C(http://www.w3.org/2001/10/xml-exc-c14n#WithComments) for EXCLUSIVE_WITH_COMMENTS, - C(http://www.w3.org/TR/2001/REC-xml-c14n-20010315) for INCLUSIVE, and - C(http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments) for INCLUSIVE_WITH_COMMENTS. + V(http://www.w3.org/2001/10/xml-exc-c14n#) for EXCLUSIVE, + V(http://www.w3.org/2001/10/xml-exc-c14n#WithComments) for EXCLUSIVE_WITH_COMMENTS, + V(http://www.w3.org/TR/2001/REC-xml-c14n-20010315) for INCLUSIVE, and + V(http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments) for INCLUSIVE_WITH_COMMENTS. saml_single_logout_service_url_post: description: @@ -523,12 +560,12 @@ options: user.info.response.signature.alg: description: - - For OpenID-Connect clients, JWA algorithm for signed UserInfo-endpoint responses. One of C(RS256) or C(unsigned). + - For OpenID-Connect clients, JWA algorithm for signed UserInfo-endpoint responses. One of V(RS256) or V(unsigned). request.object.signature.alg: description: - For OpenID-Connect clients, JWA algorithm which the client needs to use when sending - OIDC request object. One of C(any), C(none), C(RS256). + OIDC request object. One of V(any), V(none), V(RS256). use.jwks.url: description: @@ -544,9 +581,21 @@ options: - For OpenID-Connect clients, client certificate for validating JWT issued by client and signed by its key, base64-encoded. + x509.subjectdn: + description: + - For OpenID-Connect clients, subject which will be used to authenticate the client. + type: str + version_added: 9.5.0 + + x509.allow.regex.pattern.comparison: + description: + - For OpenID-Connect clients, boolean specifying whether to allow C(x509.subjectdn) as regular expression. + type: bool + version_added: 9.5.0 + extends_documentation_fragment: - - middleware_automation.keycloak.keycloak - - middleware_automation.keycloak.attributes + - middleware_automation.keycloak.keycloak + - middleware_automation.keycloak.attributes author: - Eike Frost (@eikef) @@ -587,6 +636,22 @@ EXAMPLES = ''' delegate_to: localhost +- name: Create or update a Keycloak client (minimal example), with x509 authentication + middleware_automation.keycloak.keycloak_client: + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + realm: master + state: present + client_id: test + client_authenticator_type: client-x509 + attributes: + x509.subjectdn: "CN=client" + x509.allow.regex.pattern.comparison: false + + - name: Create or update a Keycloak client (with all the bells and whistles) middleware_automation.keycloak.keycloak_client: auth_client_id: admin-cli @@ -637,7 +702,7 @@ EXAMPLES = ''' - test01 - test02 authentication_flow_binding_overrides: - browser: 4c90336b-bf1d-4b87-916d-3677ba4e5fbb + browser: 4c90336b-bf1d-4b87-916d-3677ba4e5fbb protocol_mappers: - config: access.token.claim: true @@ -717,11 +782,17 @@ end_state: ''' from ansible_collections.middleware_automation.keycloak.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 import copy +PROTOCOL_OPENID_CONNECT = 'openid-connect' +PROTOCOL_SAML = 'saml' +PROTOCOL_DOCKER_V2 = 'docker-v2' +CLIENT_META_DATA = ['authorizationServicesEnabled'] + + def normalise_cr(clientrep, remove_ids=False): """ Re-sorts any properties where the order so that diff's is minimised, and adds default values where appropriate so that the the change detection is more effective. @@ -737,6 +808,12 @@ def normalise_cr(clientrep, remove_ids=False): if 'attributes' in clientrep: clientrep['attributes'] = list(sorted(clientrep['attributes'])) + if 'defaultClientScopes' in clientrep: + clientrep['defaultClientScopes'] = list(sorted(clientrep['defaultClientScopes'])) + + if 'optionalClientScopes' in clientrep: + clientrep['optionalClientScopes'] = list(sorted(clientrep['optionalClientScopes'])) + if 'redirectUris' in clientrep: clientrep['redirectUris'] = list(sorted(clientrep['redirectUris'])) @@ -762,11 +839,70 @@ def sanitize_cr(clientrep): if 'secret' in result: result['secret'] = 'no_log' if 'attributes' in result: - if 'saml.signing.private.key' in result['attributes']: - result['attributes']['saml.signing.private.key'] = 'no_log' + attributes = result['attributes'] + if isinstance(attributes, dict) and 'saml.signing.private.key' in attributes: + attributes['saml.signing.private.key'] = 'no_log' return normalise_cr(result) +def get_authentication_flow_id(flow_name, realm, kc): + """ Get the authentication flow ID based on the flow name, realm, and Keycloak client. + + Args: + flow_name (str): The name of the authentication flow. + realm (str): The name of the realm. + kc (KeycloakClient): The Keycloak client instance. + + Returns: + str: The ID of the authentication flow. + + Raises: + KeycloakAPIException: If the authentication flow with the given name is not found in the realm. + """ + flow = kc.get_authentication_flow_by_alias(flow_name, realm) + if flow: + return flow["id"] + kc.module.fail_json(msg='Authentification flow %s not found in realm %s' % (flow_name, realm)) + + +def flow_binding_from_dict_to_model(newClientFlowBinding, realm, kc): + """ Convert a dictionary representing client flow bindings to a model representation. + + Args: + newClientFlowBinding (dict): A dictionary containing client flow bindings. + realm (str): The name of the realm. + kc (KeycloakClient): An instance of the KeycloakClient class. + + Returns: + dict: A dictionary representing the model flow bindings. The dictionary has two keys: + - "browser" (str or None): The ID of the browser authentication flow binding, or None if not provided. + - "direct_grant" (str or None): The ID of the direct grant authentication flow binding, or None if not provided. + + Raises: + KeycloakAPIException: If the authentication flow with the given name is not found in the realm. + + """ + + modelFlow = { + "browser": None, + "direct_grant": None + } + + for k, v in newClientFlowBinding.items(): + if not v: + continue + if k == "browser": + modelFlow["browser"] = v + elif k == "browser_name": + modelFlow["browser"] = get_authentication_flow_id(v, realm, kc) + elif k == "direct_grant": + modelFlow["direct_grant"] = v + elif k == "direct_grant_name": + modelFlow["direct_grant"] = get_authentication_flow_id(v, realm, kc) + + return modelFlow + + def main(): """ Module execution @@ -780,11 +916,18 @@ def main(): consentText=dict(type='str'), id=dict(type='str'), name=dict(type='str'), - protocol=dict(type='str', choices=['openid-connect', 'saml']), + protocol=dict(type='str', choices=[PROTOCOL_OPENID_CONNECT, PROTOCOL_SAML, PROTOCOL_DOCKER_V2]), protocolMapper=dict(type='str'), config=dict(type='dict'), ) + authentication_flow_spec = dict( + browser=dict(type='str'), + browser_name=dict(type='str', aliases=['browserName']), + direct_grant=dict(type='str', aliases=['directGrant']), + direct_grant_name=dict(type='str', aliases=['directGrantName']), + ) + meta_args = dict( state=dict(default='present', choices=['present', 'absent']), realm=dict(type='str', default='master'), @@ -798,7 +941,7 @@ def main(): base_url=dict(type='str', aliases=['baseUrl']), surrogate_auth_required=dict(type='bool', aliases=['surrogateAuthRequired']), enabled=dict(type='bool'), - client_authenticator_type=dict(type='str', choices=['client-secret', 'client-jwt'], aliases=['clientAuthenticatorType']), + client_authenticator_type=dict(type='str', choices=['client-secret', 'client-jwt', 'client-x509'], aliases=['clientAuthenticatorType']), secret=dict(type='str', no_log=True), registration_access_token=dict(type='str', aliases=['registrationAccessToken'], no_log=True), default_roles=dict(type='list', elements='str', aliases=['defaultRoles']), @@ -814,7 +957,7 @@ def main(): authorization_services_enabled=dict(type='bool', aliases=['authorizationServicesEnabled']), public_client=dict(type='bool', aliases=['publicClient']), frontchannel_logout=dict(type='bool', aliases=['frontchannelLogout']), - protocol=dict(type='str', choices=['openid-connect', 'saml']), + protocol=dict(type='str', choices=[PROTOCOL_OPENID_CONNECT, PROTOCOL_SAML, PROTOCOL_DOCKER_V2]), attributes=dict(type='dict'), full_scope_allowed=dict(type='bool', aliases=['fullScopeAllowed']), node_re_registration_timeout=dict(type='int', aliases=['nodeReRegistrationTimeout']), @@ -824,7 +967,13 @@ def main(): use_template_scope=dict(type='bool', aliases=['useTemplateScope']), use_template_mappers=dict(type='bool', aliases=['useTemplateMappers']), always_display_in_console=dict(type='bool', aliases=['alwaysDisplayInConsole']), - authentication_flow_binding_overrides=dict(type='dict', aliases=['authenticationFlowBindingOverrides']), + authentication_flow_binding_overrides=dict( + type='dict', + aliases=['authenticationFlowBindingOverrides'], + options=authentication_flow_spec, + required_one_of=[['browser', 'direct_grant', 'browser_name', 'direct_grant_name']], + mutually_exclusive=[['browser', 'browser_name'], ['direct_grant', 'direct_grant_name']], + ), protocol_mappers=dict(type='list', elements='dict', options=protmapper_spec, aliases=['protocolMappers']), authorization_settings=dict(type='dict', aliases=['authorizationSettings']), default_client_scopes=dict(type='list', elements='str', aliases=['defaultClientScopes']), @@ -885,7 +1034,9 @@ def main(): # Unfortunately, the ansible argument spec checker introduces variables with null values when # they are not specified if client_param == 'protocol_mappers': - new_param_value = [dict((k, v) for k, v in x.items() if x[k] is not None) for x in new_param_value] + new_param_value = [{k: v for k, v in x.items() if v is not None} for x in new_param_value] + elif client_param == 'authentication_flow_binding_overrides': + new_param_value = flow_binding_from_dict_to_model(new_param_value, realm, kc) changeset[camel(client_param)] = new_param_value @@ -912,6 +1063,8 @@ def main(): if 'clientId' not in desired_client: module.fail_json(msg='client_id needs to be specified when creating a new client') + if 'protocol' not in desired_client: + desired_client['protocol'] = PROTOCOL_OPENID_CONNECT if module._diff: result['diff'] = dict(before='', after=sanitize_cr(desired_client)) @@ -940,7 +1093,7 @@ def main(): if module._diff: result['diff'] = dict(before=sanitize_cr(before_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) diff --git a/plugins/modules/keycloak_role.py b/plugins/modules/keycloak_role.py index 558f362..c48e9c9 100644 --- a/plugins/modules/keycloak_role.py +++ b/plugins/modules/keycloak_role.py @@ -40,8 +40,8 @@ options: state: description: - State of the role. - - On C(present), the role will be created if it does not yet exist, or updated with the parameters you provide. - - On C(absent), the role will be removed if it exists. + - On V(present), the role will be created if it does not yet exist, or updated with the parameters you provide. + - On V(absent), the role will be removed if it exists. default: 'present' type: str choices: @@ -77,6 +77,42 @@ options: description: - A dict of key/value pairs to set as custom attributes for the role. - Values may be single values (e.g. a string) or a list of strings. + composite: + description: + - If V(true), the role is a composition of other realm and/or client role. + default: false + type: bool + version_added: 7.1.0 + composites: + description: + - List of roles to include to the composite realm role. + - If the composite role is a client role, the C(clientId) (not ID of the client) must be specified. + default: [] + type: list + elements: dict + version_added: 7.1.0 + suboptions: + name: + description: + - Name of the role. This can be the name of a REALM role or a client role. + type: str + required: true + client_id: + description: + - Client ID if the role is a client role. Do not include this option for a REALM role. + - Use the client ID you can see in the Keycloak console, not the technical ID of the client. + type: str + required: false + aliases: + - clientId + state: + description: + - Create the composite if present, remove it if absent. + type: str + choices: + - present + - absent + default: present extends_documentation_fragment: - middleware_automation.keycloak.keycloak @@ -142,14 +178,14 @@ EXAMPLES = ''' auth_password: PASSWORD name: my-new-role attributes: - attrib1: value1 - attrib2: value2 - attrib3: - - with - - numerous - - individual - - list - - items + attrib1: value1 + attrib2: value2 + attrib3: + - with + - numerous + - individual + - list + - items delegate_to: localhost ''' @@ -198,8 +234,9 @@ end_state: ''' from ansible_collections.middleware_automation.keycloak.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 +import copy def main(): @@ -210,6 +247,12 @@ def main(): """ argument_spec = keycloak_argument_spec() + composites_spec = dict( + name=dict(type='str', required=True), + client_id=dict(type='str', aliases=['clientId'], required=False), + state=dict(type='str', default='present', choices=['present', 'absent']) + ) + meta_args = dict( state=dict(type='str', default='present', choices=['present', 'absent']), name=dict(type='str', required=True), @@ -217,6 +260,8 @@ def main(): realm=dict(type='str', default='master'), client_id=dict(type='str'), attributes=dict(type='dict'), + composites=dict(type='list', default=[], options=composites_spec, elements='dict'), + composite=dict(type='bool', default=False), ) argument_spec.update(meta_args) @@ -250,7 +295,7 @@ def main(): # Filter and map the parameters names that apply to the role role_params = [x for x in module.params - if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm', 'client_id', 'composites'] and + if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm', 'client_id'] and module.params.get(x) is not None] # See if it already exists in Keycloak @@ -269,10 +314,10 @@ def main(): new_param_value = module.params.get(param) old_value = before_role[param] if param in before_role else None if new_param_value != old_value: - changeset[camel(param)] = new_param_value + changeset[camel(param)] = copy.deepcopy(new_param_value) # Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis) - desired_role = before_role.copy() + desired_role = copy.deepcopy(before_role) desired_role.update(changeset) result['proposed'] = changeset @@ -309,6 +354,9 @@ def main(): kc.create_client_role(desired_role, clientid, realm) after_role = kc.get_client_role(name, clientid, realm) + if after_role['composite']: + after_role['composites'] = kc.get_role_composites(rolerep=after_role, clientid=clientid, realm=realm) + result['end_state'] = after_role result['msg'] = 'Role {name} has been created'.format(name=name) @@ -316,10 +364,25 @@ def main(): else: if state == 'present': + compare_exclude = [] + if 'composites' in desired_role and isinstance(desired_role['composites'], list) and len(desired_role['composites']) > 0: + composites = kc.get_role_composites(rolerep=before_role, clientid=clientid, realm=realm) + before_role['composites'] = [] + for composite in composites: + before_composite = {} + if composite['clientRole']: + composite_client = kc.get_client_by_id(id=composite['containerId'], realm=realm) + before_composite['client_id'] = composite_client['clientId'] + else: + before_composite['client_id'] = None + before_composite['name'] = composite['name'] + before_composite['state'] = 'present' + before_role['composites'].append(before_composite) + else: + compare_exclude.append('composites') # Process an update - # no changes - if desired_role == before_role: + if is_struct_included(desired_role, before_role, exclude=compare_exclude): result['changed'] = False result['end_state'] = desired_role result['msg'] = "No changes required to role {name}.".format(name=name) @@ -341,6 +404,8 @@ def main(): else: kc.update_client_role(desired_role, clientid, realm) after_role = kc.get_client_role(name, clientid, realm) + if after_role['composite']: + after_role['composites'] = kc.get_role_composites(rolerep=after_role, clientid=clientid, realm=realm) result['end_state'] = after_role diff --git a/plugins/modules/keycloak_user_federation.py b/plugins/modules/keycloak_user_federation.py index 36fe440..864cfbc 100644 --- a/plugins/modules/keycloak_user_federation.py +++ b/plugins/modules/keycloak_user_federation.py @@ -36,9 +36,9 @@ options: state: description: - State of the user federation. - - On C(present), the user federation will be created if it does not yet exist, or updated with + - On V(present), the user federation will be created if it does not yet exist, or updated with the parameters you provide. - - On C(absent), the user federation will be removed if it exists. + - On V(absent), the user federation will be removed if it exists. default: 'present' type: str choices: @@ -54,7 +54,7 @@ options: id: description: - The unique ID for this user federation. If left empty, the user federation will be searched - by its I(name). + by its O(name). type: str name: @@ -64,18 +64,15 @@ options: provider_id: description: - - Provider for this user federation. + - Provider for this user federation. Built-in providers are V(ldap), V(kerberos), and V(sssd). + Custom user storage providers can also be used. aliases: - providerId type: str - choices: - - ldap - - kerberos - - sssd provider_type: description: - - Component type for user federation (only supported value is C(org.keycloak.storage.UserStorageProvider)). + - Component type for user federation (only supported value is V(org.keycloak.storage.UserStorageProvider)). aliases: - providerType default: org.keycloak.storage.UserStorageProvider @@ -88,13 +85,37 @@ options: - parentId type: str + remove_unspecified_mappers: + description: + - Remove mappers that are not specified in the configuration for this federation. + - Set to V(false) to keep mappers that are not listed in O(mappers). + type: bool + default: true + + bind_credential_update_mode: + description: + - The value of the config parameter O(config.bindCredential) is redacted in the Keycloak responses. + Comparing the redacted value with the desired value always evaluates to not equal. This means + the before and desired states are never equal if the parameter is set. + - Set to V(always) to include O(config.bindCredential) in the comparison of before and desired state. + Because of the redacted value returned by Keycloak the module will always detect a change + and make an update if a O(config.bindCredential) value is set. + - Set to V(only_indirect) to exclude O(config.bindCredential) when comparing the before state with the + desired state. The value of O(config.bindCredential) will only be updated if there are other changes + to the user federation that require an update. + type: str + default: always + choices: + - always + - only_indirect + config: description: - Dict specifying the configuration options for the provider; the contents differ depending on - the value of I(provider_id). Examples are given below for C(ldap), C(kerberos) and C(sssd). + the value of O(provider_id). Examples are given below for V(ldap), V(kerberos) and V(sssd). It is easiest to obtain valid config values by dumping an already-existing user federation - configuration through check-mode in the I(existing) field. - - The value C(sssd) has been supported since middleware_automation.keycloak 1.0.0. + configuration through check-mode in the RV(existing) field. + - The value V(sssd) has been supported since middleware_automation.keycloak 2.0.0. type: dict suboptions: enabled: @@ -111,15 +132,15 @@ options: importEnabled: description: - - If C(true), LDAP users will be imported into Keycloak DB and synced by the configured + - If V(true), LDAP users will be imported into Keycloak DB and synced by the configured sync policies. default: true type: bool editMode: description: - - C(READ_ONLY) is a read-only LDAP store. C(WRITABLE) means data will be synced back to LDAP - on demand. C(UNSYNCED) means user data will be imported, but not synced back to LDAP. + - V(READ_ONLY) is a read-only LDAP store. V(WRITABLE) means data will be synced back to LDAP + on demand. V(UNSYNCED) means user data will be imported, but not synced back to LDAP. type: str choices: - READ_ONLY @@ -136,13 +157,13 @@ options: vendor: description: - LDAP vendor (provider). - - Use short name. For instance, write C(rhds) for "Red Hat Directory Server". + - Use short name. For instance, write V(rhds) for "Red Hat Directory Server". type: str usernameLDAPAttribute: description: - Name of LDAP attribute, which is mapped as Keycloak username. For many LDAP server - vendors it can be C(uid). For Active directory it can be C(sAMAccountName) or C(cn). + vendors it can be V(uid). For Active directory it can be V(sAMAccountName) or V(cn). The attribute should be filled for all LDAP user records you want to import from LDAP to Keycloak. type: str @@ -151,15 +172,15 @@ options: description: - Name of LDAP attribute, which is used as RDN (top attribute) of typical user DN. Usually it's the same as Username LDAP attribute, however it is not required. For - example for Active directory, it is common to use C(cn) as RDN attribute when - username attribute might be C(sAMAccountName). + example for Active directory, it is common to use V(cn) as RDN attribute when + username attribute might be V(sAMAccountName). type: str uuidLDAPAttribute: description: - Name of LDAP attribute, which is used as unique object identifier (UUID) for objects - in LDAP. For many LDAP server vendors, it is C(entryUUID); however some are different. - For example for Active directory it should be C(objectGUID). If your LDAP server does + in LDAP. For many LDAP server vendors, it is V(entryUUID); however some are different. + For example for Active directory it should be V(objectGUID). If your LDAP server does not support the notion of UUID, you can use any other attribute that is supposed to be unique among LDAP users in tree. type: str @@ -167,7 +188,7 @@ options: userObjectClasses: description: - All values of LDAP objectClass attribute for users in LDAP divided by comma. - For example C(inetOrgPerson, organizationalPerson). Newly created Keycloak users + For example V(inetOrgPerson, organizationalPerson). Newly created Keycloak users will be written to LDAP with all those object classes and existing LDAP user records are found just if they contain all those object classes. type: str @@ -251,8 +272,8 @@ options: useTruststoreSpi: description: - Specifies whether LDAP connection will use the truststore SPI with the truststore - configured in standalone.xml/domain.xml. C(Always) means that it will always use it. - C(Never) means that it will not use it. C(Only for ldaps) means that it will use if + configured in standalone.xml/domain.xml. V(always) means that it will always use it. + V(never) means that it will not use it. V(ldapsOnly) means that it will use if your connection URL use ldaps. Note even if standalone.xml/domain.xml is not configured, the default Java cacerts or certificate specified by C(javax.net.ssl.trustStore) property will be used. @@ -297,7 +318,7 @@ options: connectionPoolingDebug: description: - A string that indicates the level of debug output to produce. Example valid values are - C(fine) (trace connection creation and removal) and C(all) (all debugging information). + V(fine) (trace connection creation and removal) and V(all) (all debugging information). type: str connectionPoolingInitSize: @@ -321,7 +342,7 @@ options: connectionPoolingProtocol: description: - A list of space-separated protocol types of connections that may be pooled. - Valid types are C(plain) and C(ssl). + Valid types are V(plain) and V(ssl). type: str connectionPoolingTimeout: @@ -342,17 +363,26 @@ options: - Name of kerberos realm. type: str + krbPrincipalAttribute: + description: + - Name of the LDAP attribute, which refers to Kerberos principal. + This is used to lookup appropriate LDAP user after successful Kerberos/SPNEGO authentication in Keycloak. + When this is empty, the LDAP user will be looked based on LDAP username corresponding + to the first part of his Kerberos principal. For instance, for principal C(john@KEYCLOAK.ORG), + it will assume that LDAP username is V(john). + type: str + serverPrincipal: description: - Full name of server principal for HTTP service including server and domain name. For - example C(HTTP/host.foo.org@FOO.ORG). Use C(*) to accept any service principal in the + example V(HTTP/host.foo.org@FOO.ORG). Use V(*) to accept any service principal in the KeyTab file. type: str keyTab: description: - Location of Kerberos KeyTab file containing the credentials of server principal. For - example C(/etc/krb5.keytab). + example V(/etc/krb5.keytab). type: str debug: @@ -427,6 +457,16 @@ options: - Max lifespan of cache entry in milliseconds. type: int + referral: + description: + - Specifies if LDAP referrals should be followed or ignored. Please note that enabling + referrals can slow down authentication as it allows the LDAP server to decide which other + LDAP servers to use. This could potentially include untrusted servers. + type: str + choices: + - ignore + - follow + mappers: description: - A list of dicts defining mappers associated with this Identity Provider. @@ -451,7 +491,7 @@ options: providerId: description: - - The mapper type for this mapper (for instance C(user-attribute-ldap-mapper)). + - The mapper type for this mapper (for instance V(user-attribute-ldap-mapper)). type: str providerType: @@ -534,14 +574,14 @@ EXAMPLES = ''' provider_id: kerberos provider_type: org.keycloak.storage.UserStorageProvider config: - priority: 0 - enabled: true - cachePolicy: DEFAULT - kerberosRealm: EXAMPLE.COM - serverPrincipal: HTTP/host.example.com@EXAMPLE.COM - keyTab: keytab - allowPasswordAuthentication: false - updateProfileFirstLogin: false + priority: 0 + enabled: true + cachePolicy: DEFAULT + kerberosRealm: EXAMPLE.COM + serverPrincipal: HTTP/host.example.com@EXAMPLE.COM + keyTab: keytab + allowPasswordAuthentication: false + updateProfileFirstLogin: false - name: Create sssd user federation middleware_automation.keycloak.keycloak_user_federation: @@ -704,16 +744,27 @@ from ansible.module_utils.six.moves.urllib.parse import urlencode from copy import deepcopy +def normalize_kc_comp(comp): + if 'config' in comp: + # kc completely removes the parameter `krbPrincipalAttribute` if it is set to `''`; the unset kc parameter is equivalent to `''`; + # to make change detection and diff more accurate we set it again in the kc responses + if 'krbPrincipalAttribute' not in comp['config']: + comp['config']['krbPrincipalAttribute'] = [''] + + # kc stores a timestamp of the last sync in `lastSync` to time the periodic sync, it is removed to minimize diff/changes + comp['config'].pop('lastSync', None) + + def sanitize(comp): compcopy = deepcopy(comp) if 'config' in compcopy: - compcopy['config'] = dict((k, v[0]) for k, v in compcopy['config'].items()) + compcopy['config'] = {k: v[0] for k, v in compcopy['config'].items()} if 'bindCredential' in compcopy['config']: compcopy['config']['bindCredential'] = '**********' if 'mappers' in compcopy: for mapper in compcopy['mappers']: if 'config' in mapper: - mapper['config'] = dict((k, v[0]) for k, v in mapper['config'].items()) + mapper['config'] = {k: v[0] for k, v in mapper['config'].items()} return compcopy @@ -760,8 +811,10 @@ def main(): priority=dict(type='int', default=0), rdnLDAPAttribute=dict(type='str'), readTimeout=dict(type='int'), + referral=dict(type='str', choices=['ignore', 'follow']), searchScope=dict(type='str', choices=['1', '2'], default='1'), serverPrincipal=dict(type='str'), + krbPrincipalAttribute=dict(type='str'), startTls=dict(type='bool', default=False), syncRegistrations=dict(type='bool', default=False), trustEmail=dict(type='bool', default=False), @@ -792,9 +845,11 @@ def main(): realm=dict(type='str', default='master'), id=dict(type='str'), name=dict(type='str'), - provider_id=dict(type='str', aliases=['providerId'], choices=['ldap', 'kerberos', 'sssd']), + provider_id=dict(type='str', aliases=['providerId']), provider_type=dict(type='str', aliases=['providerType'], default='org.keycloak.storage.UserStorageProvider'), parent_id=dict(type='str', aliases=['parentId']), + remove_unspecified_mappers=dict(type='bool', default=True), + bind_credential_update_mode=dict(type='str', default='always', choices=['always', 'only_indirect']), mappers=dict(type='list', elements='dict', options=mapper_spec), ) @@ -825,19 +880,26 @@ def main(): # Keycloak API expects config parameters to be arrays containing a single string element if config is not None: - module.params['config'] = dict((k, [str(v).lower() if not isinstance(v, str) else v]) - for k, v in config.items() if config[k] is not None) + module.params['config'] = { + k: [str(v).lower() if not isinstance(v, str) else v] + for k, v in config.items() + if config[k] is not None + } if mappers is not None: for mapper in mappers: if mapper.get('config') is not None: - mapper['config'] = dict((k, [str(v).lower() if not isinstance(v, str) else v]) - for k, v in mapper['config'].items() if mapper['config'][k] is not None) + mapper['config'] = { + k: [str(v).lower() if not isinstance(v, str) else v] + for k, v in mapper['config'].items() + if mapper['config'][k] is not None + } # Filter and map the parameters names that apply comp_params = [x for x in module.params - if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm', 'mappers'] and - module.params.get(x) is not None] + if x not in list(keycloak_argument_spec().keys()) + + ['state', 'realm', 'mappers', 'remove_unspecified_mappers', 'bind_credential_update_mode'] + and module.params.get(x) is not None] # See if it already exists in Keycloak if cid is None: @@ -855,7 +917,9 @@ def main(): # if user federation exists, get associated mappers if cid is not None and before_comp: - before_comp['mappers'] = sorted(kc.get_components(urlencode(dict(parent=cid)), realm), key=lambda x: x.get('name')) + before_comp['mappers'] = sorted(kc.get_components(urlencode(dict(parent=cid)), realm), key=lambda x: x.get('name') or '') + + normalize_kc_comp(before_comp) # Build a proposed changeset from parameters given to this module changeset = {} @@ -864,7 +928,7 @@ def main(): new_param_value = module.params.get(param) old_value = before_comp[camel(param)] if camel(param) in before_comp else None if param == 'mappers': - new_param_value = [dict((k, v) for k, v in x.items() if x[k] is not None) for x in new_param_value] + new_param_value = [{k: v for k, v in x.items() if v is not None} for x in new_param_value] if new_param_value != old_value: changeset[camel(param)] = new_param_value @@ -873,17 +937,17 @@ def main(): if module.params['provider_id'] in ['kerberos', 'sssd']: module.fail_json(msg='Cannot configure mappers for {type} provider.'.format(type=module.params['provider_id'])) for change in module.params['mappers']: - change = dict((k, v) for k, v in change.items() if change[k] is not None) + change = {k: v for k, v in change.items() if v is not None} if change.get('id') is None and change.get('name') is None: module.fail_json(msg='Either `name` or `id` has to be specified on each mapper.') if cid is None: old_mapper = {} elif change.get('id') is not None: - old_mapper = kc.get_component(change['id'], realm) + old_mapper = next((before_mapper for before_mapper in before_comp.get('mappers', []) if before_mapper["id"] == change['id']), None) if old_mapper is None: old_mapper = {} else: - found = kc.get_components(urlencode(dict(parent=cid, name=change['name'])), realm) + found = [before_mapper for before_mapper in before_comp.get('mappers', []) if before_mapper['name'] == change['name']] if len(found) > 1: module.fail_json(msg='Found multiple mappers with name `{name}`. Cannot continue.'.format(name=change['name'])) if len(found) == 1: @@ -892,10 +956,16 @@ def main(): old_mapper = {} new_mapper = old_mapper.copy() new_mapper.update(change) - if new_mapper != old_mapper: - if changeset.get('mappers') is None: - changeset['mappers'] = list() - changeset['mappers'].append(new_mapper) + # changeset contains all desired mappers: those existing, to update or to create + if changeset.get('mappers') is None: + changeset['mappers'] = list() + changeset['mappers'].append(new_mapper) + changeset['mappers'] = sorted(changeset['mappers'], key=lambda x: x.get('name') or '') + + # to keep unspecified existing mappers we add them to the desired mappers list, unless they're already present + if not module.params['remove_unspecified_mappers'] and 'mappers' in before_comp: + changeset_mapper_ids = [mapper['id'] for mapper in changeset['mappers'] if 'id' in mapper] + changeset['mappers'].extend([mapper for mapper in before_comp['mappers'] if mapper['id'] not in changeset_mapper_ids]) # Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis) desired_comp = before_comp.copy() @@ -918,50 +988,68 @@ def main(): # Process a creation result['changed'] = True - if module._diff: - result['diff'] = dict(before='', after=sanitize(desired_comp)) - if module.check_mode: + if module._diff: + result['diff'] = dict(before='', after=sanitize(desired_comp)) module.exit_json(**result) # create it - desired_comp = desired_comp.copy() - updated_mappers = desired_comp.pop('mappers', []) + desired_mappers = desired_comp.pop('mappers', []) after_comp = kc.create_component(desired_comp, realm) - cid = after_comp['id'] + updated_mappers = [] + # when creating a user federation, keycloak automatically creates default mappers + default_mappers = kc.get_components(urlencode(dict(parent=cid)), realm) - for mapper in updated_mappers: - found = kc.get_components(urlencode(dict(parent=cid, name=mapper['name'])), realm) + # create new mappers or update existing default mappers + for desired_mapper in desired_mappers: + found = [default_mapper for default_mapper in default_mappers if default_mapper['name'] == desired_mapper['name']] if len(found) > 1: - module.fail_json(msg='Found multiple mappers with name `{name}`. Cannot continue.'.format(name=mapper['name'])) + module.fail_json(msg='Found multiple mappers with name `{name}`. Cannot continue.'.format(name=desired_mapper['name'])) if len(found) == 1: old_mapper = found[0] else: old_mapper = {} new_mapper = old_mapper.copy() - new_mapper.update(mapper) + new_mapper.update(desired_mapper) if new_mapper.get('id') is not None: kc.update_component(new_mapper, realm) + updated_mappers.append(new_mapper) else: if new_mapper.get('parentId') is None: - new_mapper['parentId'] = after_comp['id'] - mapper = kc.create_component(new_mapper, realm) + new_mapper['parentId'] = cid + updated_mappers.append(kc.create_component(new_mapper, realm)) - after_comp['mappers'] = updated_mappers + if module.params['remove_unspecified_mappers']: + # we remove all unwanted default mappers + # we use ids so we dont accidently remove one of the previously updated default mapper + for default_mapper in default_mappers: + if not default_mapper['id'] in [x['id'] for x in updated_mappers]: + kc.delete_component(default_mapper['id'], realm) + + after_comp['mappers'] = kc.get_components(urlencode(dict(parent=cid)), realm) + normalize_kc_comp(after_comp) + if module._diff: + result['diff'] = dict(before='', after=sanitize(after_comp)) result['end_state'] = sanitize(after_comp) - - result['msg'] = "User federation {id} has been created".format(id=after_comp['id']) + result['msg'] = "User federation {id} has been created".format(id=cid) module.exit_json(**result) else: if state == 'present': # Process an update + desired_copy = deepcopy(desired_comp) + before_copy = deepcopy(before_comp) + # exclude bindCredential when checking wether an update is required, therefore + # updating it only if there are other changes + if module.params['bind_credential_update_mode'] == 'only_indirect': + desired_copy.get('config', []).pop('bindCredential', None) + before_copy.get('config', []).pop('bindCredential', None) # no changes - if desired_comp == before_comp: + if desired_copy == before_copy: result['changed'] = False result['end_state'] = sanitize(desired_comp) result['msg'] = "No changes required to user federation {id}.".format(id=cid) @@ -977,22 +1065,33 @@ def main(): module.exit_json(**result) # do the update - desired_comp = desired_comp.copy() - updated_mappers = desired_comp.pop('mappers', []) + desired_mappers = desired_comp.pop('mappers', []) kc.update_component(desired_comp, realm) - after_comp = kc.get_component(cid, realm) - for mapper in updated_mappers: + for before_mapper in before_comp.get('mappers', []): + # remove unwanted existing mappers that will not be updated + if not before_mapper['id'] in [x['id'] for x in desired_mappers if 'id' in x]: + kc.delete_component(before_mapper['id'], realm) + + for mapper in desired_mappers: + if mapper in before_comp.get('mappers', []): + continue if mapper.get('id') is not None: kc.update_component(mapper, realm) else: if mapper.get('parentId') is None: mapper['parentId'] = desired_comp['id'] - mapper = kc.create_component(mapper, realm) - - after_comp['mappers'] = updated_mappers - result['end_state'] = sanitize(after_comp) + kc.create_component(mapper, realm) + after_comp = kc.get_component(cid, realm) + after_comp['mappers'] = sorted(kc.get_components(urlencode(dict(parent=cid)), realm), key=lambda x: x.get('name') or '') + normalize_kc_comp(after_comp) + after_comp_sanitized = sanitize(after_comp) + before_comp_sanitized = sanitize(before_comp) + result['end_state'] = after_comp_sanitized + if module._diff: + result['diff'] = dict(before=before_comp_sanitized, after=after_comp_sanitized) + result['changed'] = before_comp_sanitized != after_comp_sanitized result['msg'] = "User federation {id} has been updated".format(id=cid) module.exit_json(**result) From 5f1b43f37ba6dcf409a38ec4958d497c7a25578b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 14 Oct 2024 10:34:20 +0200 Subject: [PATCH 314/376] update docs --- .github/workflows/traffic.yml | 14 ++++----- CHANGELOG.rst | 6 ++-- CONTRIBUTING.md | 34 ++++++++++++++++++++ README.md | 14 ++++----- docs/_gh_include/footer.inc | 4 +-- docs/index.rst | 16 +++------- docs/testing.md | 29 ++--------------- molecule/debian/converge.yml | 59 ++++++++++++++++++----------------- 8 files changed, 91 insertions(+), 85 deletions(-) diff --git a/.github/workflows/traffic.yml b/.github/workflows/traffic.yml index b4f245e..d997f4e 100644 --- a/.github/workflows/traffic.yml +++ b/.github/workflows/traffic.yml @@ -1,9 +1,9 @@ name: Collect traffic stats on: - schedule: + schedule: - cron: "51 23 * * 0" - workflow_dispatch: - + workflow_dispatch: + jobs: traffic: runs-on: ubuntu-latest @@ -11,12 +11,12 @@ jobs: - uses: actions/checkout@v2 with: ref: "gh-pages" - - - name: GitHub traffic + + - name: GitHub traffic uses: sangonzal/repository-traffic-action@v.0.1.6 env: - TRAFFIC_ACTION_TOKEN: ${{ secrets.TRIGGERING_PAT }} - + TRAFFIC_ACTION_TOKEN: ${{ secrets.TRIGGERING_PAT }} + - name: Commit changes uses: EndBug/add-and-commit@v4 with: diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7283c76..aafdac2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,6 @@ -============================================= -middleware\_automation.keycloak Release Notes -============================================= +============= +Release Notes +============= .. contents:: Topics diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aee36a6..21ddc18 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,37 @@ +## Developing + +### Build and install locally + +Clone the repository, checkout the tag you want to build, or pick the main branch for the development version; then: + + ansible-galaxy collection build . + ansible-galaxy collection install middleware_automation-keycloak-*.tar.gz + + +### Development environment + +Make sure your development machine has avilable: + +* python 3.11+ +* virtualenv +* docker (or podman) + +In order to run setup the development environment and run the molecule tests locally, after cloning the repository: + +``` +# create new virtualenv using python 3 +virtualenv $PATH_TO_DEV_VIRTUALENV +# activate the virtual env +source $PATH_TO_DEV_VIRTUALENV/bin/activate +# install ansible and tools onto the virtualenv +pip install yamllint 'molecule>=6.0' 'molecule-plugins[docker]' 'ansible-core>=2.15' ansible-lint +# install collection dependencies +ansible-galaxy collection install -r requirements.yml +# install python dependencies +pip install -r requirements.txt molecule/requirements.txt +# execute the tests (replace --all with -s subdirectory to run a single test) +molecule test --all +``` ## Contributor's Guidelines diff --git a/README.md b/README.md index 3827b90..bca0270 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Build Status](https://github.com/ansible-middleware/keycloak/workflows/CI/badge.svg?branch=main)](https://github.com/ansible-middleware/keycloak/actions/workflows/ci.yml) -> **_NOTE:_ If you are Red Hat customer, install `redhat.sso` (for Red Hat Single Sign-On) or `redhat.rhbk` (for Red Hat Build of Keycloak) from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection.** +> **_NOTE:_ If you are Red Hat customer, install `redhat.rhbk` (for Red Hat Build of Keycloak) or `redhat.sso` (for Red Hat Single Sign-On) from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection.** @@ -49,9 +49,10 @@ A requirement file is provided to install: ### Included roles -* [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service (keycloak <= 19.0). -* [`keycloak_realm`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md): role for configuring a realm, user federation(s), clients and users, in an installed service. -* [`keycloak_quarkus`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_quarkus/README.md): role for installing the quarkus variant of keycloak (>= 17.0.0). +* `keycloak_quarkus`: role for installing keycloak (>= 19.0.0, quarkus based). +* `keycloak_realm`: role for configuring a realm, user federation(s), clients and users, in an installed service. +* `keycloak`: role for installing legacy keycloak (<= 19.0, wildfly based). + ## Usage @@ -61,7 +62,7 @@ A requirement file is provided to install: * [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs keycloak legacy based on the defined variables (using most defaults). * [`playbooks/keycloak_quarkus.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak_quarkus.yml) installs keycloak >= 17 based on the defined variables (using most defaults). - + Both playbooks include the `keycloak` role, with different settings, as described in the following sections. For full service configuration details, refer to the [keycloak role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md). @@ -92,7 +93,7 @@ Execute the following command from the source root directory ``` ansible-playbook -i -e @rhn-creds.yml playbooks/keycloak.yml -e keycloak_admin_password= -``` +``` - `keycloak_admin_password` Password for the administration console user account. - `ansible_hosts` is the inventory, below is an example inventory for deploying to localhost @@ -143,4 +144,3 @@ Apache License v2.0 or later See [LICENSE](LICENSE) to view the full text. - diff --git a/docs/_gh_include/footer.inc b/docs/_gh_include/footer.inc index 73bac34..11c1cfe 100644 --- a/docs/_gh_include/footer.inc +++ b/docs/_gh_include/footer.inc @@ -7,7 +7,7 @@
-

© Copyright 2022, Red Hat, Inc.

+

© Copyright 2024, Red Hat, Inc.

Built with Sphinx using a theme @@ -18,4 +18,4 @@ - \ No newline at end of file + diff --git a/docs/index.rst b/docs/index.rst index 38dec5b..6c46ab1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,31 +10,25 @@ Welcome to Keycloak Collection documentation README plugins/index roles/index + Changelog .. toctree:: :maxdepth: 2 :caption: Developer documentation - testing - developing - releasing - -.. toctree:: - :maxdepth: 2 - :caption: General - - Changelog + Developing + Testing + Releasing .. toctree:: :maxdepth: 2 :caption: Middleware collections - Infinispan / Red Hat Data Grid Keycloak / Red Hat Single Sign-On + Infinispan / Red Hat Data Grid Wildfly / Red Hat JBoss EAP Tomcat / Red Hat JWS ActiveMQ / Red Hat AMQ Broker Kafka / Red Hat AMQ Streams Ansible Middleware utilities - Red Hat CSP Download JCliff diff --git a/docs/testing.md b/docs/testing.md index 1d06d7f..8e773ea 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -4,24 +4,7 @@ The collection is tested with a [molecule](https://github.com/ansible-community/molecule) setup covering the included roles and verifying correct installation and idempotency. In order to run the molecule tests locally with python 3.9 available, after cloning the repository: - -``` -pip install yamllint 'molecule[docker]~=3.5.2' ansible-core flake8 ansible-lint voluptuous -molecule test --all -``` - - -## Integration testing - -Demo repositories which depend on the collection, and aggregate functionality with other middleware_automation collections, are automatically rebuilt -at every collection release to ensure non-breaking changes and consistent behaviour. - -The repository are: - - - [Flange demo](https://github.com/ansible-middleware/flange-demo) - A deployment of Wildfly cluster integrated with keycloak and infinispan. - - [CrossDC keycloak demo](https://github.com/ansible-middleware/cross-dc-rhsso-demo) - A clustered multi-regional installation of keycloak with infinispan remote caches. +The test scenarios are available on the source code repository each on his own subdirectory under [molecule/](https://github.com/ansible-middleware/keycloak/molecule). ## Test playbooks @@ -29,15 +12,7 @@ The repository are: Sample playbooks are provided in the `playbooks/` directory; to run the playbooks locally (requires a rhel system with python 3.9+, ansible, and systemd) the steps are as follows: ``` -# setup environment -pip install ansible-core -# clone the repository -git clone https://github.com/ansible-middleware/keycloak -cd keycloak -# install collection dependencies -ansible-galaxy collection install -r requirements.yml -# install collection python deps -pip install -r requirements.txt +# setup environment as in developing # create inventory for localhost cat << EOF > inventory [keycloak] diff --git a/molecule/debian/converge.yml b/molecule/debian/converge.yml index e6319b7..5b60408 100644 --- a/molecule/debian/converge.yml +++ b/molecule/debian/converge.yml @@ -7,36 +7,39 @@ keycloak_realm: TestRealm keycloak_quarkus_log: file keycloak_quarkus_frontend_url: 'http://localhost:8080/' - keycloak_quarkus_start_dev: True + keycloak_quarkus_start_dev: true keycloak_quarkus_proxy_mode: none - keycloak_client_default_roles: - - TestRoleAdmin - - TestRoleUser - keycloak_client_users: - - username: TestUser - password: password - client_roles: - - client: TestClient - role: TestRoleUser - - username: TestAdmin - password: password - client_roles: - - client: TestClient - role: TestRoleUser - - client: TestClient - role: TestRoleAdmin - keycloak_clients: - - name: TestClient - roles: "{{ keycloak_client_default_roles }}" - public_client: "{{ keycloak_client_public }}" - web_origins: "{{ keycloak_client_web_origins }}" - users: "{{ keycloak_client_users }}" - client_id: TestClient - attributes: - post.logout.redirect.uris: '/public/logout' roles: - role: keycloak_quarkus - role: keycloak_realm - keycloak_realm: TestRealm - keycloak_admin_password: "remembertochangeme" keycloak_context: '' + keycloak_client_default_roles: + - TestRoleAdmin + - TestRoleUser + keycloak_client_users: + - username: TestUser + password: password + client_roles: + - client: TestClient + role: TestRoleUser + realm: "{{ keycloak_realm }}" + - username: TestAdmin + password: password + client_roles: + - client: TestClient + role: TestRoleUser + realm: "{{ keycloak_realm }}" + - client: TestClient + role: TestRoleAdmin + realm: "{{ keycloak_realm }}" + keycloak_realm: TestRealm + keycloak_clients: + - name: TestClient + roles: "{{ keycloak_client_default_roles }}" + realm: "{{ keycloak_realm }}" + public_client: "{{ keycloak_client_public }}" + web_origins: "{{ keycloak_client_web_origins }}" + users: "{{ keycloak_client_users }}" + client_id: TestClient + attributes: + post.logout.redirect.uris: '/public/logout' From be19ec1289805dea625d93e5b36357e1004f0e46 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Mon, 14 Oct 2024 10:41:17 +0200 Subject: [PATCH 315/376] update tests --- README.md | 2 +- molecule/debian/converge.yml | 8 +- molecule/default/converge.yml | 6 +- plugins/modules/keycloak_realm.py | 848 +++++++++++++++++++ roles/keycloak_realm/README.md | 2 +- roles/keycloak_realm/defaults/main.yml | 2 +- roles/keycloak_realm/meta/argument_specs.yml | 2 +- roles/keycloak_realm/tasks/main.yml | 4 +- 8 files changed, 857 insertions(+), 17 deletions(-) create mode 100644 plugins/modules/keycloak_realm.py diff --git a/README.md b/README.md index bca0270..e8c289e 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,8 @@ A requirement file is provided to install: ### Install Playbook -* [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs keycloak legacy based on the defined variables (using most defaults). * [`playbooks/keycloak_quarkus.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak_quarkus.yml) installs keycloak >= 17 based on the defined variables (using most defaults). +* [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs keycloak legacy based on the defined variables (using most defaults). Both playbooks include the `keycloak` role, with different settings, as described in the following sections. diff --git a/molecule/debian/converge.yml b/molecule/debian/converge.yml index 5b60408..1a7d267 100644 --- a/molecule/debian/converge.yml +++ b/molecule/debian/converge.yml @@ -4,18 +4,15 @@ vars: keycloak_quarkus_show_deprecation_warnings: false keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_realm: TestRealm + keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_host: instance keycloak_quarkus_log: file - keycloak_quarkus_frontend_url: 'http://localhost:8080/' keycloak_quarkus_start_dev: true keycloak_quarkus_proxy_mode: none roles: - role: keycloak_quarkus - role: keycloak_realm keycloak_context: '' - keycloak_client_default_roles: - - TestRoleAdmin - - TestRoleUser keycloak_client_users: - username: TestUser password: password @@ -35,7 +32,6 @@ keycloak_realm: TestRealm keycloak_clients: - name: TestClient - roles: "{{ keycloak_client_default_roles }}" realm: "{{ keycloak_realm }}" public_client: "{{ keycloak_client_public }}" web_origins: "{{ keycloak_client_web_origins }}" diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index bb8c552..417713f 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -9,7 +9,7 @@ keycloak_quarkus_log: file keycloak_quarkus_log_level: debug keycloak_quarkus_log_target: /tmp/keycloak - keycloak_quarkus_start_dev: True + keycloak_quarkus_start_dev: true keycloak_quarkus_proxy_mode: none keycloak_quarkus_offline_install: true keycloak_quarkus_download_path: /tmp/keycloak/ @@ -17,9 +17,6 @@ - role: keycloak_quarkus - role: keycloak_realm keycloak_context: '' - keycloak_client_default_roles: - - TestRoleAdmin - - TestRoleUser keycloak_client_users: - username: TestUser password: password @@ -39,7 +36,6 @@ keycloak_realm: TestRealm keycloak_clients: - name: TestClient - roles: "{{ keycloak_client_default_roles }}" realm: "{{ keycloak_realm }}" public_client: "{{ keycloak_client_public }}" web_origins: "{{ keycloak_client_web_origins }}" diff --git a/plugins/modules/keycloak_realm.py b/plugins/modules/keycloak_realm.py new file mode 100644 index 0000000..a22795b --- /dev/null +++ b/plugins/modules/keycloak_realm.py @@ -0,0 +1,848 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2017, Eike Frost +# Copyright (c) 2021, Christophe Gilles +# 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 + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: keycloak_realm + +short_description: Allows administration of Keycloak realm via Keycloak API + +version_added: 3.0.0 + +description: + - This module allows the administration of Keycloak realm via the Keycloak REST API. It + requires access to the REST API via OpenID Connect; the user connecting and the realm 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 realm definition with the scope tailored + to your needs and a user having the expected roles. + + - The names of module options are snake_cased versions of the camelCase ones found in the + Keycloak API and its documentation at U(https://www.keycloak.org/docs-api/8.0/rest-api/index.html). + Aliases are provided so camelCased versions can be used as well. + + - The Keycloak API does not always sanity check inputs e.g. you can set + SAML-specific settings on an OpenID Connect client for instance and vice versa. Be careful. + If you do not specify a setting, usually a sensible default is chosen. + +attributes: + check_mode: + support: full + diff_mode: + support: full + +options: + state: + description: + - State of the realm. + - On V(present), the realm will be created (or updated if it exists already). + - On V(absent), the realm will be removed if it exists. + choices: ['present', 'absent'] + default: 'present' + type: str + + id: + description: + - The realm to create. + type: str + realm: + description: + - The realm name. + type: str + access_code_lifespan: + description: + - The realm access code lifespan. + aliases: + - accessCodeLifespan + type: int + access_code_lifespan_login: + description: + - The realm access code lifespan login. + aliases: + - accessCodeLifespanLogin + type: int + access_code_lifespan_user_action: + description: + - The realm access code lifespan user action. + aliases: + - accessCodeLifespanUserAction + type: int + access_token_lifespan: + description: + - The realm access token lifespan. + aliases: + - accessTokenLifespan + type: int + access_token_lifespan_for_implicit_flow: + description: + - The realm access token lifespan for implicit flow. + aliases: + - accessTokenLifespanForImplicitFlow + type: int + account_theme: + description: + - The realm account theme. + aliases: + - accountTheme + type: str + action_token_generated_by_admin_lifespan: + description: + - The realm action token generated by admin lifespan. + aliases: + - actionTokenGeneratedByAdminLifespan + type: int + action_token_generated_by_user_lifespan: + description: + - The realm action token generated by user lifespan. + aliases: + - actionTokenGeneratedByUserLifespan + type: int + admin_events_details_enabled: + description: + - The realm admin events details enabled. + aliases: + - adminEventsDetailsEnabled + type: bool + admin_events_enabled: + description: + - The realm admin events enabled. + aliases: + - adminEventsEnabled + type: bool + admin_theme: + description: + - The realm admin theme. + aliases: + - adminTheme + type: str + attributes: + description: + - The realm attributes. + type: dict + browser_flow: + description: + - The realm browser flow. + aliases: + - browserFlow + type: str + browser_security_headers: + description: + - The realm browser security headers. + aliases: + - browserSecurityHeaders + type: dict + brute_force_protected: + description: + - The realm brute force protected. + aliases: + - bruteForceProtected + type: bool + client_authentication_flow: + description: + - The realm client authentication flow. + aliases: + - clientAuthenticationFlow + type: str + client_scope_mappings: + description: + - The realm client scope mappings. + aliases: + - clientScopeMappings + type: dict + default_default_client_scopes: + description: + - The realm default default client scopes. + aliases: + - defaultDefaultClientScopes + type: list + elements: str + default_groups: + description: + - The realm default groups. + aliases: + - defaultGroups + type: list + elements: str + default_locale: + description: + - The realm default locale. + aliases: + - defaultLocale + type: str + default_optional_client_scopes: + description: + - The realm default optional client scopes. + aliases: + - defaultOptionalClientScopes + type: list + elements: str + default_roles: + description: + - The realm default roles. + aliases: + - defaultRoles + type: list + elements: str + default_signature_algorithm: + description: + - The realm default signature algorithm. + aliases: + - defaultSignatureAlgorithm + type: str + direct_grant_flow: + description: + - The realm direct grant flow. + aliases: + - directGrantFlow + type: str + display_name: + description: + - The realm display name. + aliases: + - displayName + type: str + display_name_html: + description: + - The realm display name HTML. + aliases: + - displayNameHtml + type: str + docker_authentication_flow: + description: + - The realm docker authentication flow. + aliases: + - dockerAuthenticationFlow + type: str + duplicate_emails_allowed: + description: + - The realm duplicate emails allowed option. + aliases: + - duplicateEmailsAllowed + type: bool + edit_username_allowed: + description: + - The realm edit username allowed option. + aliases: + - editUsernameAllowed + type: bool + email_theme: + description: + - The realm email theme. + aliases: + - emailTheme + type: str + enabled: + description: + - The realm enabled option. + type: bool + enabled_event_types: + description: + - The realm enabled event types. + aliases: + - enabledEventTypes + type: list + elements: str + events_enabled: + description: + - Enables or disables login events for this realm. + aliases: + - eventsEnabled + type: bool + version_added: 3.6.0 + events_expiration: + description: + - The realm events expiration. + aliases: + - eventsExpiration + type: int + events_listeners: + description: + - The realm events listeners. + aliases: + - eventsListeners + type: list + elements: str + failure_factor: + description: + - The realm failure factor. + aliases: + - failureFactor + type: int + internationalization_enabled: + description: + - The realm internationalization enabled option. + aliases: + - internationalizationEnabled + type: bool + login_theme: + description: + - The realm login theme. + aliases: + - loginTheme + type: str + login_with_email_allowed: + description: + - The realm login with email allowed option. + aliases: + - loginWithEmailAllowed + type: bool + max_delta_time_seconds: + description: + - The realm max delta time in seconds. + aliases: + - maxDeltaTimeSeconds + type: int + max_failure_wait_seconds: + description: + - The realm max failure wait in seconds. + aliases: + - maxFailureWaitSeconds + type: int + minimum_quick_login_wait_seconds: + description: + - The realm minimum quick login wait in seconds. + aliases: + - minimumQuickLoginWaitSeconds + type: int + not_before: + description: + - The realm not before. + aliases: + - notBefore + type: int + offline_session_idle_timeout: + description: + - The realm offline session idle timeout. + aliases: + - offlineSessionIdleTimeout + type: int + offline_session_max_lifespan: + description: + - The realm offline session max lifespan. + aliases: + - offlineSessionMaxLifespan + type: int + offline_session_max_lifespan_enabled: + description: + - The realm offline session max lifespan enabled option. + aliases: + - offlineSessionMaxLifespanEnabled + type: bool + otp_policy_algorithm: + description: + - The realm otp policy algorithm. + aliases: + - otpPolicyAlgorithm + type: str + otp_policy_digits: + description: + - The realm otp policy digits. + aliases: + - otpPolicyDigits + type: int + otp_policy_initial_counter: + description: + - The realm otp policy initial counter. + aliases: + - otpPolicyInitialCounter + type: int + otp_policy_look_ahead_window: + description: + - The realm otp policy look ahead window. + aliases: + - otpPolicyLookAheadWindow + type: int + otp_policy_period: + description: + - The realm otp policy period. + aliases: + - otpPolicyPeriod + type: int + otp_policy_type: + description: + - The realm otp policy type. + aliases: + - otpPolicyType + type: str + otp_supported_applications: + description: + - The realm otp supported applications. + aliases: + - otpSupportedApplications + type: list + elements: str + password_policy: + description: + - The realm password policy. + aliases: + - passwordPolicy + type: str + permanent_lockout: + description: + - The realm permanent lockout. + aliases: + - permanentLockout + type: bool + quick_login_check_milli_seconds: + description: + - The realm quick login check in milliseconds. + aliases: + - quickLoginCheckMilliSeconds + type: int + refresh_token_max_reuse: + description: + - The realm refresh token max reuse. + aliases: + - refreshTokenMaxReuse + type: int + registration_allowed: + description: + - The realm registration allowed option. + aliases: + - registrationAllowed + type: bool + registration_email_as_username: + description: + - The realm registration email as username option. + aliases: + - registrationEmailAsUsername + type: bool + registration_flow: + description: + - The realm registration flow. + aliases: + - registrationFlow + type: str + remember_me: + description: + - The realm remember me option. + aliases: + - rememberMe + type: bool + reset_credentials_flow: + description: + - The realm reset credentials flow. + aliases: + - resetCredentialsFlow + type: str + reset_password_allowed: + description: + - The realm reset password allowed option. + aliases: + - resetPasswordAllowed + type: bool + revoke_refresh_token: + description: + - The realm revoke refresh token option. + aliases: + - revokeRefreshToken + type: bool + smtp_server: + description: + - The realm smtp server. + aliases: + - smtpServer + type: dict + ssl_required: + description: + - The realm ssl required option. + choices: ['all', 'external', 'none'] + aliases: + - sslRequired + type: str + sso_session_idle_timeout: + description: + - The realm sso session idle timeout. + aliases: + - ssoSessionIdleTimeout + type: int + sso_session_idle_timeout_remember_me: + description: + - The realm sso session idle timeout remember me. + aliases: + - ssoSessionIdleTimeoutRememberMe + type: int + sso_session_max_lifespan: + description: + - The realm sso session max lifespan. + aliases: + - ssoSessionMaxLifespan + type: int + sso_session_max_lifespan_remember_me: + description: + - The realm sso session max lifespan remember me. + aliases: + - ssoSessionMaxLifespanRememberMe + type: int + supported_locales: + description: + - The realm supported locales. + aliases: + - supportedLocales + type: list + elements: str + user_managed_access_allowed: + description: + - The realm user managed access allowed option. + aliases: + - userManagedAccessAllowed + type: bool + verify_email: + description: + - The realm verify email option. + aliases: + - verifyEmail + type: bool + wait_increment_seconds: + description: + - The realm wait increment in seconds. + aliases: + - waitIncrementSeconds + type: int + +extends_documentation_fragment: + - middleware_automation.keycloak.keycloak + - middleware_automation.keycloak.attributes + +author: + - Christophe Gilles (@kris2kris) +''' + +EXAMPLES = ''' +- name: Create or update Keycloak realm (minimal example) + middleware_automation.keycloak.keycloak_realm: + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + id: realm + realm: realm + state: present + +- name: Delete a Keycloak realm + middleware_automation.keycloak.keycloak_realm: + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + id: test + state: absent +''' + +RETURN = ''' +msg: + description: Message as to what action was taken. + returned: always + type: str + sample: "Realm testrealm has been updated" + +proposed: + description: Representation of proposed realm. + returned: always + type: dict + sample: { + id: "test" + } + +existing: + description: Representation of existing realm (sample is truncated). + returned: always + type: dict + sample: { + "adminUrl": "http://www.example.com/admin_url", + "attributes": { + "request.object.signature.alg": "RS256", + } + } + +end_state: + description: Representation of realm after module execution (sample is truncated). + returned: on success + type: dict + sample: { + "adminUrl": "http://www.example.com/admin_url", + "attributes": { + "request.object.signature.alg": "RS256", + } + } +''' + +from ansible_collections.middleware_automation.keycloak.plugins.module_utils.identity.keycloak.keycloak import KeycloakAPI, camel, \ + keycloak_argument_spec, get_token, KeycloakError +from ansible.module_utils.basic import AnsibleModule + + +def normalise_cr(realmrep): + """ Re-sorts any properties where the order is important so that diff's is minimised and the change detection is more effective. + + :param realmrep: the realmrep dict to be sanitized + :return: normalised realmrep dict + """ + # Avoid the dict passed in to be modified + realmrep = realmrep.copy() + + if 'enabledEventTypes' in realmrep: + realmrep['enabledEventTypes'] = list(sorted(realmrep['enabledEventTypes'])) + + if 'otpSupportedApplications' in realmrep: + realmrep['otpSupportedApplications'] = list(sorted(realmrep['otpSupportedApplications'])) + + if 'supportedLocales' in realmrep: + realmrep['supportedLocales'] = list(sorted(realmrep['supportedLocales'])) + + return realmrep + + +def sanitize_cr(realmrep): + """ Removes probably sensitive details from a realm representation. + + :param realmrep: the realmrep dict to be sanitized + :return: sanitized realmrep dict + """ + result = realmrep.copy() + if 'secret' in result: + result['secret'] = '********' + if 'attributes' in result: + if 'saml.signing.private.key' in result['attributes']: + result['attributes'] = result['attributes'].copy() + result['attributes']['saml.signing.private.key'] = '********' + return normalise_cr(result) + + +def main(): + """ + Module execution + + :return: + """ + argument_spec = keycloak_argument_spec() + + meta_args = dict( + state=dict(default='present', choices=['present', 'absent']), + + id=dict(type='str'), + realm=dict(type='str'), + access_code_lifespan=dict(type='int', aliases=['accessCodeLifespan']), + access_code_lifespan_login=dict(type='int', aliases=['accessCodeLifespanLogin']), + access_code_lifespan_user_action=dict(type='int', aliases=['accessCodeLifespanUserAction']), + access_token_lifespan=dict(type='int', aliases=['accessTokenLifespan'], no_log=False), + access_token_lifespan_for_implicit_flow=dict(type='int', aliases=['accessTokenLifespanForImplicitFlow'], no_log=False), + account_theme=dict(type='str', aliases=['accountTheme']), + action_token_generated_by_admin_lifespan=dict(type='int', aliases=['actionTokenGeneratedByAdminLifespan'], no_log=False), + action_token_generated_by_user_lifespan=dict(type='int', aliases=['actionTokenGeneratedByUserLifespan'], no_log=False), + admin_events_details_enabled=dict(type='bool', aliases=['adminEventsDetailsEnabled']), + admin_events_enabled=dict(type='bool', aliases=['adminEventsEnabled']), + admin_theme=dict(type='str', aliases=['adminTheme']), + attributes=dict(type='dict'), + browser_flow=dict(type='str', aliases=['browserFlow']), + browser_security_headers=dict(type='dict', aliases=['browserSecurityHeaders']), + brute_force_protected=dict(type='bool', aliases=['bruteForceProtected']), + client_authentication_flow=dict(type='str', aliases=['clientAuthenticationFlow']), + client_scope_mappings=dict(type='dict', aliases=['clientScopeMappings']), + default_default_client_scopes=dict(type='list', elements='str', aliases=['defaultDefaultClientScopes']), + default_groups=dict(type='list', elements='str', aliases=['defaultGroups']), + default_locale=dict(type='str', aliases=['defaultLocale']), + default_optional_client_scopes=dict(type='list', elements='str', aliases=['defaultOptionalClientScopes']), + default_roles=dict(type='list', elements='str', aliases=['defaultRoles']), + default_signature_algorithm=dict(type='str', aliases=['defaultSignatureAlgorithm']), + direct_grant_flow=dict(type='str', aliases=['directGrantFlow']), + display_name=dict(type='str', aliases=['displayName']), + display_name_html=dict(type='str', aliases=['displayNameHtml']), + docker_authentication_flow=dict(type='str', aliases=['dockerAuthenticationFlow']), + duplicate_emails_allowed=dict(type='bool', aliases=['duplicateEmailsAllowed']), + edit_username_allowed=dict(type='bool', aliases=['editUsernameAllowed']), + email_theme=dict(type='str', aliases=['emailTheme']), + enabled=dict(type='bool'), + enabled_event_types=dict(type='list', elements='str', aliases=['enabledEventTypes']), + events_enabled=dict(type='bool', aliases=['eventsEnabled']), + events_expiration=dict(type='int', aliases=['eventsExpiration']), + events_listeners=dict(type='list', elements='str', aliases=['eventsListeners']), + failure_factor=dict(type='int', aliases=['failureFactor']), + internationalization_enabled=dict(type='bool', aliases=['internationalizationEnabled']), + login_theme=dict(type='str', aliases=['loginTheme']), + login_with_email_allowed=dict(type='bool', aliases=['loginWithEmailAllowed']), + max_delta_time_seconds=dict(type='int', aliases=['maxDeltaTimeSeconds']), + max_failure_wait_seconds=dict(type='int', aliases=['maxFailureWaitSeconds']), + minimum_quick_login_wait_seconds=dict(type='int', aliases=['minimumQuickLoginWaitSeconds']), + not_before=dict(type='int', aliases=['notBefore']), + offline_session_idle_timeout=dict(type='int', aliases=['offlineSessionIdleTimeout']), + offline_session_max_lifespan=dict(type='int', aliases=['offlineSessionMaxLifespan']), + offline_session_max_lifespan_enabled=dict(type='bool', aliases=['offlineSessionMaxLifespanEnabled']), + otp_policy_algorithm=dict(type='str', aliases=['otpPolicyAlgorithm']), + otp_policy_digits=dict(type='int', aliases=['otpPolicyDigits']), + otp_policy_initial_counter=dict(type='int', aliases=['otpPolicyInitialCounter']), + otp_policy_look_ahead_window=dict(type='int', aliases=['otpPolicyLookAheadWindow']), + otp_policy_period=dict(type='int', aliases=['otpPolicyPeriod']), + otp_policy_type=dict(type='str', aliases=['otpPolicyType']), + otp_supported_applications=dict(type='list', elements='str', aliases=['otpSupportedApplications']), + password_policy=dict(type='str', aliases=['passwordPolicy'], no_log=False), + permanent_lockout=dict(type='bool', aliases=['permanentLockout']), + quick_login_check_milli_seconds=dict(type='int', aliases=['quickLoginCheckMilliSeconds']), + refresh_token_max_reuse=dict(type='int', aliases=['refreshTokenMaxReuse'], no_log=False), + registration_allowed=dict(type='bool', aliases=['registrationAllowed']), + registration_email_as_username=dict(type='bool', aliases=['registrationEmailAsUsername']), + registration_flow=dict(type='str', aliases=['registrationFlow']), + remember_me=dict(type='bool', aliases=['rememberMe']), + reset_credentials_flow=dict(type='str', aliases=['resetCredentialsFlow']), + reset_password_allowed=dict(type='bool', aliases=['resetPasswordAllowed'], no_log=False), + revoke_refresh_token=dict(type='bool', aliases=['revokeRefreshToken']), + smtp_server=dict(type='dict', aliases=['smtpServer']), + ssl_required=dict(choices=["external", "all", "none"], aliases=['sslRequired']), + sso_session_idle_timeout=dict(type='int', aliases=['ssoSessionIdleTimeout']), + sso_session_idle_timeout_remember_me=dict(type='int', aliases=['ssoSessionIdleTimeoutRememberMe']), + sso_session_max_lifespan=dict(type='int', aliases=['ssoSessionMaxLifespan']), + sso_session_max_lifespan_remember_me=dict(type='int', aliases=['ssoSessionMaxLifespanRememberMe']), + supported_locales=dict(type='list', elements='str', aliases=['supportedLocales']), + user_managed_access_allowed=dict(type='bool', aliases=['userManagedAccessAllowed']), + verify_email=dict(type='bool', aliases=['verifyEmail']), + wait_increment_seconds=dict(type='int', aliases=['waitIncrementSeconds']), + ) + + argument_spec.update(meta_args) + + module = AnsibleModule(argument_spec=argument_spec, + supports_check_mode=True, + required_one_of=([['id', 'realm', 'enabled'], + ['token', 'auth_realm', 'auth_username', 'auth_password']]), + required_together=([['auth_realm', 'auth_username', 'auth_password']])) + + result = dict(changed=False, msg='', diff={}, proposed={}, existing={}, end_state={}) + + # 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) + + realm = module.params.get('realm') + state = module.params.get('state') + + # convert module parameters to realm representation parameters (if they belong in there) + params_to_ignore = list(keycloak_argument_spec().keys()) + ['state'] + + # Filter and map the parameters names that apply to the role + realm_params = [x for x in module.params + if x not in params_to_ignore and + module.params.get(x) is not None] + + # See whether the realm already exists in Keycloak + before_realm = kc.get_realm_by_id(realm=realm) + + if before_realm is None: + before_realm = {} + + # Build a proposed changeset from parameters given to this module + changeset = {} + + for realm_param in realm_params: + new_param_value = module.params.get(realm_param) + changeset[camel(realm_param)] = new_param_value + + # Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis) + desired_realm = before_realm.copy() + desired_realm.update(changeset) + + result['proposed'] = sanitize_cr(changeset) + before_realm_sanitized = sanitize_cr(before_realm) + result['existing'] = before_realm_sanitized + + # Cater for when it doesn't exist (an empty dict) + if not before_realm: + if state == 'absent': + # Do nothing and exit + if module._diff: + result['diff'] = dict(before='', after='') + result['changed'] = False + result['end_state'] = {} + result['msg'] = 'Realm does not exist, doing nothing.' + module.exit_json(**result) + + # Process a creation + result['changed'] = True + + if 'id' not in desired_realm: + module.fail_json(msg='id needs to be specified when creating a new realm') + + if module._diff: + result['diff'] = dict(before='', after=sanitize_cr(desired_realm)) + + if module.check_mode: + module.exit_json(**result) + + # create it + kc.create_realm(desired_realm) + after_realm = kc.get_realm_by_id(desired_realm['id']) + + result['end_state'] = sanitize_cr(after_realm) + + result['msg'] = 'Realm %s has been created.' % desired_realm['id'] + module.exit_json(**result) + + else: + if state == 'present': + # Process an update + + # doing an update + result['changed'] = True + if module.check_mode: + # We can only compare the current realm with the proposed updates we have + before_norm = normalise_cr(before_realm) + desired_norm = normalise_cr(desired_realm) + if module._diff: + result['diff'] = dict(before=sanitize_cr(before_norm), + after=sanitize_cr(desired_norm)) + result['changed'] = (before_norm != desired_norm) + + module.exit_json(**result) + + # do the update + kc.update_realm(desired_realm, realm=realm) + + after_realm = kc.get_realm_by_id(realm=realm) + + if before_realm == after_realm: + result['changed'] = False + + result['end_state'] = sanitize_cr(after_realm) + + if module._diff: + result['diff'] = dict(before=before_realm_sanitized, + after=sanitize_cr(after_realm)) + + result['msg'] = 'Realm %s has been updated.' % desired_realm['id'] + module.exit_json(**result) + + else: + # Process a deletion (because state was not 'present') + result['changed'] = True + + if module._diff: + result['diff'] = dict(before=before_realm_sanitized, after='') + + if module.check_mode: + module.exit_json(**result) + + # delete it + kc.delete_realm(realm=realm) + + result['proposed'] = {} + result['end_state'] = {} + + result['msg'] = 'Realm %s has been deleted.' % before_realm['id'] + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/roles/keycloak_realm/README.md b/roles/keycloak_realm/README.md index d6ce30c..179784e 100644 --- a/roles/keycloak_realm/README.md +++ b/roles/keycloak_realm/README.md @@ -19,7 +19,7 @@ Role Defaults |`keycloak_management_http_port`| Management port | `9990` | |`keycloak_auth_client`| Authentication client for configuration REST calls | `admin-cli` | |`keycloak_client_public`| Configure a public realm client | `True` | -|`keycloak_client_web_origins`| Web origins for realm client | `+` | +|`keycloak_client_web_origins`| Web origins for realm client | `/*` | |`keycloak_url`| URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port }}` | |`keycloak_management_url`| URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port }}` | diff --git a/roles/keycloak_realm/defaults/main.yml b/roles/keycloak_realm/defaults/main.yml index e488207..b9e1e45 100644 --- a/roles/keycloak_realm/defaults/main.yml +++ b/roles/keycloak_realm/defaults/main.yml @@ -43,7 +43,7 @@ keycloak_client_default_roles: [] keycloak_client_public: true # allowed web origins for the client -keycloak_client_web_origins: '+' +keycloak_client_web_origins: '/*' # list of user and role mappings to create in the client # Each user has the form: diff --git a/roles/keycloak_realm/meta/argument_specs.yml b/roles/keycloak_realm/meta/argument_specs.yml index b124be2..7c24a7c 100644 --- a/roles/keycloak_realm/meta/argument_specs.yml +++ b/roles/keycloak_realm/meta/argument_specs.yml @@ -53,7 +53,7 @@ argument_specs: type: "bool" keycloak_client_web_origins: # line 42 of keycloak_realm/defaults/main.yml - default: "+" + default: "/*" description: "Web origins for realm client" type: "str" keycloak_client_users: diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index 016ab55..962016c 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -82,7 +82,7 @@ base_url: "{{ item.base_url | default('') }}" enabled: "{{ item.enabled | default(True) }}" redirect_uris: "{{ item.redirect_uris | default(omit) }}" - web_origins: "{{ item.web_origins | default('+') }}" + web_origins: "{{ item.web_origins | default(omit) }}" bearer_only: "{{ item.bearer_only | default(omit) }}" standard_flow_enabled: "{{ item.standard_flow_enabled | default(omit) }}" implicit_flow_enabled: "{{ item.implicit_flow_enabled | default(omit) }}" @@ -92,7 +92,7 @@ protocol: "{{ item.protocol | default(omit) }}" attributes: "{{ item.attributes | default(omit) }}" state: present - no_log: "{{ keycloak_no_log | default('True') }}" + no_log: "{{ keycloak_no_log | default('false') }}" register: create_client_result loop: "{{ keycloak_clients | flatten }}" when: (item.name is defined and item.client_id is defined) or (item.name is defined and item.id is defined) From 1279937bb0e95f0398ad04494b5f6797bd21afd6 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 16 Oct 2024 08:56:53 +0200 Subject: [PATCH 316/376] Update keycloak to 24.0.5 --- molecule/default/prepare.yml | 2 +- molecule/quarkus/converge.yml | 2 +- roles/keycloak_quarkus/README.md | 4 ++-- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index a50dfa4..899dabd 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -22,7 +22,7 @@ - name: Download keycloak archive to controller directory ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user - url: https://github.com/keycloak/keycloak/releases/download/24.0.4/keycloak-24.0.4.zip + url: https://github.com/keycloak/keycloak/releases/download/24.0.5/keycloak-24.0.5.zip dest: /tmp/keycloak mode: '0640' delegate_to: localhost diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 7c86756..0860a42 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -37,7 +37,7 @@ repository_url: https://repo1.maven.org/maven2/ # https://mvnrepository.com/artifact/org.keycloak/keycloak-kerberos-federation/24.0.4 group_id: org.keycloak artifact_id: keycloak-kerberos-federation - version: 24.0.4 # optional + version: 24.0.5 # optional # username: myUser # optional # password: myPAT # optional # - id: my-static-theme diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 00c785f..034c021 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -33,7 +33,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `24.0.4` | +|`keycloak_quarkus_version`| keycloak.org package version | `24.0.5` | |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | @@ -207,7 +207,7 @@ keycloak_quarkus_providers: repository_url: https://maven.pkg.github.com/OWNER/REPOSITORY # optional, maven repo url group_id: my.group # optional, maven group id artifact_id: artifact # optional, maven artifact id - version: 24.0.4 # optional, defaults to latest + version: 24.0.5 # optional, defaults to latest username: user # optional, cf. https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry#authenticating-to-github-packages password: pat # optional, provide a PAT for accessing Github's Apache Maven registry properties: # optional, list of key-values diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index b029fee..148d84d 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 24.0.4 +keycloak_quarkus_version: 24.0.5 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 34ec365..51fd6d8 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -2,7 +2,7 @@ argument_specs: main: options: keycloak_quarkus_version: - default: "24.0.4" + default: "24.0.5" description: "keycloak.org package version" type: "str" keycloak_quarkus_archive: From f6fdae4aa80283c9155f0e203efeb5f8b9d7bc22 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 16 Oct 2024 07:24:42 +0000 Subject: [PATCH 317/376] Update changelog for release 2.4.3 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 14 +++++++++++--- changelogs/changelog.yaml | 9 +++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index aafdac2..37a3923 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,11 +1,19 @@ -============= -Release Notes -============= +============================================= +middleware\_automation.keycloak Release Notes +============================================= .. contents:: Topics This changelog describes changes after version 0.2.6. +v2.4.3 +====== + +Minor Changes +------------- + +- Update keycloak to 24.0.5 `#241 `_ + v2.4.2 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 41a4076..40a7db3 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -604,3 +604,12 @@ releases: - 237.yaml - 239.yaml release_date: '2024-09-26' + 2.4.3: + changes: + minor_changes: + - 'Update keycloak to 24.0.5 `#241 `_ + + ' + fragments: + - 241.yaml + release_date: '2024-10-16' From 333d55ad734a21018d7c8bf02d6f66cb66d46933 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 16 Oct 2024 07:24:57 +0000 Subject: [PATCH 318/376] Bump version to 2.4.4 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index a782353..a6511a8 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.4.3" +version: "2.4.4" readme: README.md authors: - Romain Pelisse From 68a0f8842332a82133a6e6b0b77eb6c84e73c8a0 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Fri, 22 Nov 2024 08:08:09 +0100 Subject: [PATCH 319/376] keycloak_quarkus: Rebuild config and restart service for local providers (#249) --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/tasks/install.yml | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 034c021..e63db68 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -200,7 +200,7 @@ keycloak_quarkus_providers: - id: http-client # required; "{{ id }}.jar" identifies the file name on RHBK spi: connections # required if neither url, local_path nor maven are specified; required for setting properties default: true # optional, whether to set default for spi, default false - restart: true # optional, whether to restart, default true + restart: true # optional, whether to rebuild config and restart the service after deploying, default true url: https://.../.../custom_spi.jar # optional, url for download via http local_path: my_theme_spi.jar # optional, path on local controller for SPI to be uploaded maven: # optional, for download using maven diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 809e07e..d8ce657 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -218,7 +218,7 @@ become: true loop: "{{ keycloak_quarkus_providers }}" when: item.url is defined and item.url | length > 0 - notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or not item.restart else [] }}" + notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" # this requires the `lxml` package to be installed; we redirect this step to localhost such that we do need to install it on the remote hosts - name: "Download custom providers to localhost using maven" @@ -235,7 +235,7 @@ loop: "{{ keycloak_quarkus_providers }}" when: item.maven is defined no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" - notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or not item.restart else [] }}" + notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" - name: "Copy maven providers" ansible.builtin.copy: @@ -249,7 +249,7 @@ when: item.maven is defined no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" -- name: "Copy providers" +- name: "Copy local providers" ansible.builtin.copy: src: "{{ item.local_path }}" dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar" @@ -259,6 +259,7 @@ become: true loop: "{{ keycloak_quarkus_providers }}" when: item.local_path is defined + notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" - name: Ensure required folder structure for policies exists ansible.builtin.file: From d1859aaff28f77312f7fc04f4fd0c37a7ace5770 Mon Sep 17 00:00:00 2001 From: Ranabir Chakraborty Date: Tue, 3 Dec 2024 22:12:36 +0530 Subject: [PATCH 320/376] Access token lifespan is too short for ansible run --- .github/workflows/ci.yml | 2 +- roles/keycloak_realm/tasks/main.yml | 3 +++ .../keycloak_realm/tasks/manage_token_lifespan.yml | 14 ++++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 roles/keycloak_realm/tasks/manage_token_lifespan.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3d71b46..de65d72 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,4 +16,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode", "quarkus_upgrade", "debian", "quarkus_ha" ] + [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode", "quarkus_upgrade", "debian", "quarkus_ha" ] diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index 962016c..8f33fcc 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -110,3 +110,6 @@ loop_control: loop_var: client when: "'users' in client" + +- name: Provide Access token lifespan + ansible.builtin.include_tasks: manage_token_lifespan.yml diff --git a/roles/keycloak_realm/tasks/manage_token_lifespan.yml b/roles/keycloak_realm/tasks/manage_token_lifespan.yml new file mode 100644 index 0000000..f16b938 --- /dev/null +++ b/roles/keycloak_realm/tasks/manage_token_lifespan.yml @@ -0,0 +1,14 @@ +--- +- name: "Update Access token lifespan" + ansible.builtin.uri: + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}" + method: PUT + body: + accessTokenLifespan: 300 + validate_certs: false + body_format: json + status_code: + - 200 + - 204 + headers: + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" From 5f534ca5669514244176c1b53bb3552b3d65fe75 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Thu, 12 Dec 2024 09:05:09 +0100 Subject: [PATCH 321/376] keycloak_quarkus: Add theme cache invalidation handler --- roles/keycloak_quarkus/handlers/main.yml | 3 +++ roles/keycloak_quarkus/tasks/install.yml | 6 +++--- .../keycloak_quarkus/tasks/invalidate_theme_cache.yml | 11 +++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 roles/keycloak_quarkus/tasks/invalidate_theme_cache.yml diff --git a/roles/keycloak_quarkus/handlers/main.yml b/roles/keycloak_quarkus/handlers/main.yml index 37d65c5..eec7789 100644 --- a/roles/keycloak_quarkus/handlers/main.yml +++ b/roles/keycloak_quarkus/handlers/main.yml @@ -1,4 +1,7 @@ --- +- name: "Invalidate {{ keycloak.service_name }} theme cache" + ansible.builtin.include_tasks: invalidate_theme_cache.yml + listen: "invalidate keycloak theme cache" # handler should be invoked anytime a [build configuration](https://www.keycloak.org/server/all-config?f=build) changes - name: "Rebuild {{ keycloak.service_name }} config" ansible.builtin.include_tasks: rebuild_config.yml diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index d8ce657..c602d8c 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -218,7 +218,7 @@ become: true loop: "{{ keycloak_quarkus_providers }}" when: item.url is defined and item.url | length > 0 - notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" + notify: "{{ ['invalidate keycloak theme cache', 'rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" # this requires the `lxml` package to be installed; we redirect this step to localhost such that we do need to install it on the remote hosts - name: "Download custom providers to localhost using maven" @@ -235,7 +235,7 @@ loop: "{{ keycloak_quarkus_providers }}" when: item.maven is defined no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" - notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" + notify: "{{ ['invalidate keycloak theme cache', 'rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" - name: "Copy maven providers" ansible.builtin.copy: @@ -259,7 +259,7 @@ become: true loop: "{{ keycloak_quarkus_providers }}" when: item.local_path is defined - notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" + notify: "{{ ['invalidate keycloak theme cache', 'rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" - name: Ensure required folder structure for policies exists ansible.builtin.file: diff --git a/roles/keycloak_quarkus/tasks/invalidate_theme_cache.yml b/roles/keycloak_quarkus/tasks/invalidate_theme_cache.yml new file mode 100644 index 0000000..90ff67f --- /dev/null +++ b/roles/keycloak_quarkus/tasks/invalidate_theme_cache.yml @@ -0,0 +1,11 @@ +--- +# From https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/24.0/html/server_developer_guide/themes#creating_a_theme: +# If you want to manually delete the content of the themes cache, +# you can do so by deleting the data/tmp/kc-gzip-cache directory of the server distribution +# It can be useful for instance if you redeployed custom providers or custom themes without +# disabling themes caching in the previous server executions. +- name: "Delete {{ keycloak.service_name }} theme cache directory" + ansible.builtin.file: + path: "{{ keycloak.home }}/data/tmp/kc-gzip-cache" + state: absent + become: true From 5d15d37890ef472e65e420e4824bf83691913087 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Thu, 5 Dec 2024 13:26:10 +0100 Subject: [PATCH 322/376] RHBK v26: Raise default KC+RHBK versions to v26.x (#253) --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index e63db68..9211b00 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -33,7 +33,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `24.0.5` | +|`keycloak_quarkus_version`| keycloak.org package version | `26.0.7` | |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 148d84d..4d158c8 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 24.0.5 +keycloak_quarkus_version: 26.0.7 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 51fd6d8..d1a3a0e 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -2,7 +2,7 @@ argument_specs: main: options: keycloak_quarkus_version: - default: "24.0.5" + default: "26.0.7" description: "keycloak.org package version" type: "str" keycloak_quarkus_archive: @@ -468,7 +468,7 @@ argument_specs: downstream: options: rhbk_version: - default: "24.0.3" + default: "26.0.6" description: "Red Hat Build of Keycloak version" type: "str" rhbk_archive: From bf0bd9e1da64eb0a5a764b9275acd226da9e75bf Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Thu, 5 Dec 2024 13:26:57 +0100 Subject: [PATCH 323/376] RHBK v26: Update mssqj jdbc driver (KC/RHBK v26 Support #253) As per --- roles/keycloak_quarkus/defaults/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 4d158c8..ba9854b 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -138,9 +138,9 @@ keycloak_quarkus_default_jdbc: version: 2.7.4 mssql: url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;' - version: 12.4.2 - driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.4.2.jre11/mssql-jdbc-12.4.2.jre11.jar" - # cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/24.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver + version: 12.8.1 + driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.8.1.jre11/mssql-jdbc-12.8.1.jre11.jar" + # cf. https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/server_configuration_guide/index#db-installing-the-microsoft-sql-server-driver ### logging configuration keycloak_quarkus_log: file keycloak_quarkus_log_level: info From 0c58ae48ff949f1c8152f8076b296e4b551db011 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 9 Dec 2024 14:48:15 +0100 Subject: [PATCH 324/376] RHBK v26: Update ispn session usages (KC/RHBK v26 Support #253) Cf. --- roles/keycloak_quarkus/templates/cache-ispn.xml.j2 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 index fb11cda..8ead247 100644 --- a/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 +++ b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 @@ -18,8 +18,8 @@ + xsi:schemaLocation="urn:infinispan:config:15.0 http://www.infinispan.org/schemas/infinispan-config-15.0.xsd" + xmlns="urn:infinispan:config:15.0"> {% set stack_expression='' %} {% if keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING' %} @@ -55,18 +55,22 @@
+ + + + @@ -98,4 +102,4 @@
- \ No newline at end of file + From 58233549a7f99d3a534a4ae77d87884c5846f348 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 9 Dec 2024 14:54:24 +0100 Subject: [PATCH 325/376] keycloak.conf: Remove `config-keystore-type` (KC/RHBK v26 Support #253) Cf. --- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 1 - 1 file changed, 1 deletion(-) diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index ab4024b..24972c3 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -21,7 +21,6 @@ hostname-strict-https=false # Config store config-keystore={{ keycloak_quarkus_config_key_store_file }} config-keystore-password={{ keycloak_quarkus_config_key_store_password }} -config-keystore-type=PKCS12 {% endif %} # Observability From 277e1336ee97318ca88ffd27e3fe0ea2bf0e8133 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 9 Dec 2024 15:47:06 +0100 Subject: [PATCH 326/376] RHBK v26: Migrate to `keycloak_quarkus_bootstrap_admin_user[_password]` (Process for creation of admin account changed #248) --- molecule/debian/converge.yml | 4 +- molecule/debian/verify.yml | 2 +- molecule/default/converge.yml | 4 +- molecule/default/verify.yml | 4 +- molecule/https_revproxy/converge.yml | 4 +- molecule/quarkus-devmode/converge.yml | 4 +- molecule/quarkus/converge.yml | 4 +- molecule/quarkus/verify.yml | 4 +- molecule/quarkus_ha/converge.yml | 4 +- molecule/quarkus_upgrade/vars.yml | 3 +- molecule/quarkus_upgrade/verify.yml | 4 +- roles/keycloak_quarkus/README.md | 8 +- roles/keycloak_quarkus/defaults/main.yml | 4 +- .../keycloak_quarkus/meta/argument_specs.yml | 8 +- roles/keycloak_quarkus/tasks/deprecations.yml | 96 +++++++++++++++++++ roles/keycloak_quarkus/tasks/main.yml | 2 +- roles/keycloak_quarkus/tasks/prereqs.yml | 4 +- .../templates/keycloak-sysconfig.j2 | 4 +- 18 files changed, 132 insertions(+), 35 deletions(-) diff --git a/molecule/debian/converge.yml b/molecule/debian/converge.yml index 1a7d267..a3ba17a 100644 --- a/molecule/debian/converge.yml +++ b/molecule/debian/converge.yml @@ -3,8 +3,8 @@ hosts: all vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_quarkus_host: instance keycloak_quarkus_log: file keycloak_quarkus_start_dev: true diff --git a/molecule/debian/verify.yml b/molecule/debian/verify.yml index 59bf483..863b820 100644 --- a/molecule/debian/verify.yml +++ b/molecule/debian/verify.yml @@ -2,7 +2,7 @@ - name: Verify hosts: all vars: - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_uri: "http://localhost:{{ 8080 + ( keycloak_jboss_port_offset | default(0) ) }}" keycloak_management_port: "http://localhost:{{ 9990 + ( keycloak_jboss_port_offset | default(0) ) }}" keycloak_jboss_port_offset: 10 diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index 417713f..543b003 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -3,8 +3,8 @@ hosts: all vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_quarkus_host: instance keycloak_quarkus_log: file keycloak_quarkus_log_level: debug diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index b880105..eac4339 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -2,7 +2,7 @@ - name: Verify hosts: all vars: - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_uri: "http://localhost:8080" tasks: - name: Populate service facts @@ -16,7 +16,7 @@ ansible.builtin.uri: url: "{{ keycloak_uri }}/realms/master/protocol/openid-connect/token" method: POST - body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password" + body: "client_id=admin-cli&username=admin&password={{ keycloak_quarkus_bootstrap_admin_user }}&grant_type=password" validate_certs: no register: keycloak_auth_response until: keycloak_auth_response.status == 200 diff --git a/molecule/https_revproxy/converge.yml b/molecule/https_revproxy/converge.yml index b490721..b25d731 100644 --- a/molecule/https_revproxy/converge.yml +++ b/molecule/https_revproxy/converge.yml @@ -3,8 +3,8 @@ hosts: all vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_realm: TestRealm keycloak_quarkus_host: instance keycloak_quarkus_log: file diff --git a/molecule/quarkus-devmode/converge.yml b/molecule/quarkus-devmode/converge.yml index 2e5d351..5cd4ea1 100644 --- a/molecule/quarkus-devmode/converge.yml +++ b/molecule/quarkus-devmode/converge.yml @@ -3,8 +3,8 @@ hosts: all vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_realm: TestRealm keycloak_quarkus_log: file keycloak_quarkus_frontend_url: 'http://localhost:8080/' diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 0860a42..d134203 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -3,8 +3,8 @@ hosts: all vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_realm: TestRealm keycloak_quarkus_host: instance keycloak_quarkus_log: file diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 63769dc..1ee3b61 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -2,7 +2,7 @@ - name: Verify hosts: all vars: - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" tasks: - name: Populate service facts ansible.builtin.service_facts: @@ -91,7 +91,7 @@ ansible.builtin.uri: url: "https://instance:8443/realms/master/protocol/openid-connect/token" method: POST - body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password" + body: "client_id=admin-cli&username=admin&password={{ keycloak_quarkus_bootstrap_admin_user }}&grant_type=password" validate_certs: no register: keycloak_auth_response until: keycloak_auth_response.status == 200 diff --git a/molecule/quarkus_ha/converge.yml b/molecule/quarkus_ha/converge.yml index 00246b8..0455351 100644 --- a/molecule/quarkus_ha/converge.yml +++ b/molecule/quarkus_ha/converge.yml @@ -3,8 +3,8 @@ hosts: keycloak vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_realm: TestRealm keycloak_quarkus_host: "{{ inventory_hostname }}" keycloak_quarkus_log: file diff --git a/molecule/quarkus_upgrade/vars.yml b/molecule/quarkus_upgrade/vars.yml index 81d56b5..6a60844 100644 --- a/molecule/quarkus_upgrade/vars.yml +++ b/molecule/quarkus_upgrade/vars.yml @@ -1,7 +1,6 @@ --- keycloak_quarkus_offline_install: false -keycloak_quarkus_admin_password: "remembertochangeme" -keycloak_quarkus_admin_pass: "remembertochangeme" +keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_realm: TestRealm keycloak_quarkus_host: instance keycloak_quarkus_log: file diff --git a/molecule/quarkus_upgrade/verify.yml b/molecule/quarkus_upgrade/verify.yml index f5edfd0..3214d9f 100644 --- a/molecule/quarkus_upgrade/verify.yml +++ b/molecule/quarkus_upgrade/verify.yml @@ -2,7 +2,7 @@ - name: Verify hosts: instance vars: - keycloak_quarkus_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_port: http://localhost:8080 tasks: - name: Populate service facts @@ -24,7 +24,7 @@ ansible.builtin.uri: url: "{{ keycloak_quarkus_port }}/realms/master/protocol/openid-connect/token" method: POST - body: "client_id=admin-cli&username=admin&password={{ keycloak_quarkus_admin_password }}&grant_type=password" + body: "client_id=admin-cli&username=admin&password={{ keycloak_quarkus_bootstrap_admin_password }}&grant_type=password" validate_certs: no register: keycloak_auth_response until: keycloak_auth_response.status == 200 diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 9211b00..cf45cdf 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -44,7 +44,8 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_admin_user`| Administration console user account | `admin` | +|`keycloak_quarkus_bootstrap_admin_user`| Administration console user account | `admin` | +|`keycloak_quarkus_admin_user`| Deprecated, use `keycloak_quarkus_bootstrap_admin_user` instead. | | |`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | |`keycloak_quarkus_host`| Hostname for the Keycloak server | `localhost` | |`keycloak_quarkus_port`| The port used by the proxy when exposing the hostname | `-1` | @@ -243,7 +244,8 @@ Role Variables | Variable | Description | Required | |:---------|:------------|----------| -|`keycloak_quarkus_admin_pass`| Password of console admin account | `yes` | +|`keycloak_quarkus_bootstrap_admin_password`| Password of console admin account | `yes` | +|`keycloak_quarkus_admin_pass`| Deprecated, use `keycloak_quarkus_bootstrap_admin_password` instead. | | |`keycloak_quarkus_frontend_url`| Base URL for frontend URLs, including scheme, host, port and path | `no` | |`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` | |`keycloak_quarkus_ks_vault_pass`| The password for accessing the keystore vault SPI | `no` | @@ -265,7 +267,7 @@ The role uses the following [custom facts](https://docs.ansible.com/ansible/late | Variable | Description | |:---------|:------------| -|`general.bootstrapped` | A custom fact indicating whether this role has been used for bootstrapping keycloak on the respective host before; set to `false` (e.g., when starting off with a new, empty database) ensures that the initial admin user as defined by `keycloak_quarkus_admin_user[_pass]` gets created | +|`general.bootstrapped` | A custom fact indicating whether this role has been used for bootstrapping keycloak on the respective host before; set to `false` (e.g., when starting off with a new, empty database) ensures that the initial admin user as defined by `keycloak_quarkus_bootstrap_admin_user[_password]` gets created | License ------- diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index ba9854b..f425396 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -27,8 +27,8 @@ keycloak_quarkus_configure_firewalld: false keycloak_quarkus_configure_iptables: false ### administrator console password -keycloak_quarkus_admin_user: admin -keycloak_quarkus_admin_pass: +keycloak_quarkus_bootstrap_admin_user: admin +keycloak_quarkus_bootstrap_admin_password: keycloak_quarkus_master_realm: master ### Configuration settings diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index d1a3a0e..f91bc90 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -68,13 +68,13 @@ argument_specs: default: "10s" description: "systemd RestartSec for service" type: "str" - keycloak_quarkus_admin_user: + keycloak_quarkus_bootstrap_admin_user: default: "admin" - description: "Administration console user account" + description: "Administration user account, only for bootstrapping" type: "str" - keycloak_quarkus_admin_pass: + keycloak_quarkus_bootstrap_admin_password: required: true - description: "Password of console admin account" + description: "Password of admin account, only for bootstrapping" type: "str" keycloak_quarkus_master_realm: default: "master" diff --git a/roles/keycloak_quarkus/tasks/deprecations.yml b/roles/keycloak_quarkus/tasks/deprecations.yml index 27ea6e3..fe269e9 100644 --- a/roles/keycloak_quarkus/tasks/deprecations.yml +++ b/roles/keycloak_quarkus/tasks/deprecations.yml @@ -49,5 +49,101 @@ notify: - print deprecation warning +# https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options +- name: Check deprecation of keycloak_quarkus_frontend_url -> keycloak_quarkus_hostname + when: + - keycloak_quarkus_hostname is not defined + - keycloak_quarkus_frontend_url is defined + - keycloak_quarkus_frontend_url != '' + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_hostname: "{{ keycloak_quarkus_frontend_url }}" + deprecated_variable: "keycloak_quarkus_frontend_url" # read in deprecation handler + notify: + - print deprecation warning + +# https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options +- name: Check deprecation of keycloak_quarkus_hostname_strict_https + keycloak_quarkus_host + keycloak_quarkus_port + keycloak_quarkus_path -> keycloak_quarkus_hostname + when: + - keycloak_quarkus_hostname is not defined + - keycloak_quarkus_hostname_strict_https is defined or keycloak_quarkus_frontend_url is defined or keycloak_quarkus_port is defined or keycloak_quarkus_path is defined + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_hostname: >- + {% set protocol = '' %} + {% if keycloak_quarkus_hostname_strict_https %} + {% set protocol = 'https://' %} + {% elif keycloak_quarkus_hostname_strict_https is defined and keycloak_quarkus_hostname_strict_https is False %} + {% set protocol = 'http://' %} + {% endif %} + {{ protocol }}{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_port }}/{{ keycloak_quarkus_path }} + deprecated_variable: "keycloak_quarkus_hostname_strict_https or keycloak_quarkus_frontend_url or keycloak_quarkus_frontend_url or keycloak_quarkus_hostname" # read in deprecation handler + notify: + - print deprecation warning + +# https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options +- name: Check deprecation of keycloak_quarkus_admin_url -> keycloak_quarkus_admin + when: + - keycloak_quarkus_admin is not defined + - keycloak_quarkus_admin_url is defined + - keycloak_quarkus_admin_url != '' + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_admin: "{{ keycloak_quarkus_admin_url }}" + deprecated_variable: "keycloak_quarkus_admin_url" # read in deprecation handler + notify: + - print deprecation warning + +# https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options +- name: Check deprecation of keycloak_quarkus_hostname_strict_backchannel -> keycloak_quarkus_hostname_backchannel_dynamic + when: + - keycloak_quarkus_hostname_backchannel_dynamic is not defined + - keycloak_quarkus_hostname_strict_backchannel is defined + - keycloak_quarkus_hostname_strict_backchannel != '' + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_hostname_backchannel_dynamic: "{{ keycloak_quarkus_hostname_strict_backchannel == False }}" + deprecated_variable: "keycloak_quarkus_hostname_backchannel_dynamic" # read in deprecation handler + notify: + - print deprecation warning + +# https://github.com/keycloak/keycloak/issues/30009 +- name: Check deprecation of keycloak_quarkus_admin_user -> keycloak_quarkus_bootstrap_admin_user + when: + - keycloak_quarkus_bootstrap_admin_user is not defined + - keycloak_quarkus_admin_user is defined + - keycloak_quarkus_admin_user != '' + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_bootstrap_admin_user: "{{ keycloak_quarkus_admin_user }}" + deprecated_variable: "keycloak_quarkus_admin_user" # read in deprecation handler + notify: + - print deprecation warning + +# https://github.com/keycloak/keycloak/issues/30009 +- name: Check deprecation of keycloak_quarkus_admin_pass -> keycloak_quarkus_bootstrap_admin_password + when: + - keycloak_quarkus_bootstrap_admin_password is not defined + - keycloak_quarkus_admin_pass is defined + - keycloak_quarkus_admin_pass != '' + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_bootstrap_admin_user: "{{ keycloak_quarkus_admin_pass }}" + deprecated_variable: "keycloak_quarkus_admin_pass" # read in deprecation handler + notify: + - print deprecation warning + - name: Flush handlers ansible.builtin.meta: flush_handlers diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index bb86b2c..cca6764 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -91,7 +91,7 @@ register: keycloak_service_status changed_when: false -- name: "Notify to remove `keycloak_quarkus_admin_user[_pass]` env vars" +- name: "Notify to remove `keycloak_quarkus_bootstrap_admin_user[_password]` env vars" when: - not ansible_local.keycloak.general.bootstrapped | default(false) | bool # it was not bootstrapped prior to the current role's execution - keycloak_service_status.status.ActiveState == "active" # but it is now diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 0835aab..db7555e 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -2,9 +2,9 @@ - name: Validate admin console password ansible.builtin.assert: that: - - keycloak_quarkus_admin_pass | length > 12 + - keycloak_quarkus_bootstrap_admin_password | length > 12 quiet: true - fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass to a 12+ char long string" + fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_bootstrap_admin_password to a 12+ char long string" success_msg: "{{ 'Console administrator password OK' }}" - name: Validate relative path diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index 2c260a3..244d9aa 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -1,7 +1,7 @@ {{ ansible_managed | comment }} {% if not ansible_local.keycloak.general.bootstrapped | default(false) | bool %} -KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} -KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' +KC_BOOTSTRAP_ADMIN_USERNAME={{ keycloak_quarkus_bootstrap_admin_user }} +KC_BOOTSTRAP_ADMIN_PASSWORD='{{ keycloak_quarkus_bootstrap_admin_password }}' {% else %} {{ keycloak.bootstrap_mnemonic }} {% endif %} From 213449ec58813bb038ceb79ce4ddc2f887c10cf7 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 9 Dec 2024 15:35:05 +0100 Subject: [PATCH 327/376] RHBK v26: Add hostname v2 (KC/RHBK v26 Support #253) Cf. https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options - especially the removed options --- molecule/debian/converge.yml | 2 +- molecule/default/converge.yml | 2 +- molecule/https_revproxy/converge.yml | 2 +- molecule/quarkus/converge.yml | 2 +- molecule/quarkus_ha/converge.yml | 2 +- molecule/quarkus_upgrade/vars.yml | 2 +- playbooks/keycloak_quarkus.yml | 2 +- playbooks/keycloak_quarkus_dev.yml | 2 +- roles/keycloak_quarkus/README.md | 16 +++++---- roles/keycloak_quarkus/defaults/main.yml | 13 +++---- .../keycloak_quarkus/meta/argument_specs.yml | 34 +++++++++---------- .../templates/keycloak.conf.j2 | 19 ++--------- roles/keycloak_quarkus/vars/main.yml | 2 +- 13 files changed, 43 insertions(+), 57 deletions(-) diff --git a/molecule/debian/converge.yml b/molecule/debian/converge.yml index a3ba17a..7fab040 100644 --- a/molecule/debian/converge.yml +++ b/molecule/debian/converge.yml @@ -5,7 +5,7 @@ keycloak_quarkus_show_deprecation_warnings: false keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" - keycloak_quarkus_host: instance + keycloak_quarkus_hostname: http://instance keycloak_quarkus_log: file keycloak_quarkus_start_dev: true keycloak_quarkus_proxy_mode: none diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index 543b003..13a771b 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -5,7 +5,7 @@ keycloak_quarkus_show_deprecation_warnings: false keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" - keycloak_quarkus_host: instance + keycloak_quarkus_hostname: http://instance keycloak_quarkus_log: file keycloak_quarkus_log_level: debug keycloak_quarkus_log_target: /tmp/keycloak diff --git a/molecule/https_revproxy/converge.yml b/molecule/https_revproxy/converge.yml index b25d731..7245265 100644 --- a/molecule/https_revproxy/converge.yml +++ b/molecule/https_revproxy/converge.yml @@ -6,7 +6,7 @@ keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_realm: TestRealm - keycloak_quarkus_host: instance + keycloak_quarkus_hostname: http://instance keycloak_quarkus_log: file keycloak_quarkus_http_enabled: True keycloak_quarkus_http_port: 8080 diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index d134203..9b7b3a7 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -6,7 +6,7 @@ keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_realm: TestRealm - keycloak_quarkus_host: instance + keycloak_quarkus_hostname: http://instance keycloak_quarkus_log: file keycloak_quarkus_log_level: debug # needed for the verify step keycloak_quarkus_https_key_file_enabled: true diff --git a/molecule/quarkus_ha/converge.yml b/molecule/quarkus_ha/converge.yml index 0455351..238fbb5 100644 --- a/molecule/quarkus_ha/converge.yml +++ b/molecule/quarkus_ha/converge.yml @@ -6,7 +6,7 @@ keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_realm: TestRealm - keycloak_quarkus_host: "{{ inventory_hostname }}" + keycloak_quarkus_hostname: "http://{{ inventory_hostname }}" keycloak_quarkus_log: file keycloak_quarkus_log_level: info keycloak_quarkus_https_key_file_enabled: true diff --git a/molecule/quarkus_upgrade/vars.yml b/molecule/quarkus_upgrade/vars.yml index 6a60844..52ab103 100644 --- a/molecule/quarkus_upgrade/vars.yml +++ b/molecule/quarkus_upgrade/vars.yml @@ -2,7 +2,7 @@ keycloak_quarkus_offline_install: false keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_realm: TestRealm -keycloak_quarkus_host: instance +keycloak_quarkus_hostname: http://instance keycloak_quarkus_log: file keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_log_target: /tmp/keycloak diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index f2649a5..84d1774 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -3,7 +3,7 @@ hosts: all vars: keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_quarkus_host: localhost + keycloak_quarkus_hostname: http://localhost keycloak_quarkus_port: 8443 keycloak_quarkus_log: file keycloak_quarkus_proxy_mode: none diff --git a/playbooks/keycloak_quarkus_dev.yml b/playbooks/keycloak_quarkus_dev.yml index 533db79..0c74c36 100644 --- a/playbooks/keycloak_quarkus_dev.yml +++ b/playbooks/keycloak_quarkus_dev.yml @@ -3,7 +3,7 @@ hosts: all vars: keycloak_admin_password: "remembertochangeme" - keycloak_quarkus_host: localhost + keycloak_quarkus_hostname: http://localhost keycloak_quarkus_port: 8080 keycloak_quarkus_log: file keycloak_quarkus_start_dev: true diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index cf45cdf..7f0542a 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -47,9 +47,9 @@ Role Defaults |`keycloak_quarkus_bootstrap_admin_user`| Administration console user account | `admin` | |`keycloak_quarkus_admin_user`| Deprecated, use `keycloak_quarkus_bootstrap_admin_user` instead. | | |`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | -|`keycloak_quarkus_host`| Hostname for the Keycloak server | `localhost` | -|`keycloak_quarkus_port`| The port used by the proxy when exposing the hostname | `-1` | -|`keycloak_quarkus_path`| This should be set if proxy uses a different context-path for Keycloak | | +|`keycloak_quarkus_host`| Deprecated, use `keycloak_quarkus_hostname` instead. | | +|`keycloak_quarkus_port`| Deprecated, use `keycloak_quarkus_hostname` instead. | | +|`keycloak_quarkus_path`| Deprecated, use `keycloak_quarkus_hostname` instead. | | |`keycloak_quarkus_http_port`| HTTP listening port | `8080` | |`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` | @@ -64,8 +64,10 @@ Role Defaults |`keycloak_quarkus_java_jvm_opts`| Other JVM settings | same as keycloak | |`keycloak_quarkus_java_opts`| JVM arguments; if overridden, it takes precedence over `keycloak_quarkus_java_*` | `{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}` | |`keycloak_quarkus_additional_env_vars` | List of additional env variables of { key: str, value: str} to be put in sysconfig file | `[]` | -|`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | | -|`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | | +|`keycloak_quarkus_hostname`| Address at which is the server exposed. Can be a full URL, or just a hostname. When only hostname is provided, scheme, port and context path are resolved from the request. | | +|`keycloak_quarkus_frontend_url`| Deprecated, use `keycloak_quarkus_hostname` instead. | | +|`keycloak_quarkus_admin`| Set the base URL for accessing the administration console, including scheme, host, port and path | | +|`keycloak_quarkus_admin_url`| Deprecated, use `keycloak_quarkus_admin` instead. | | |`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | |`keycloak_quarkus_health_check_url_path`| Path to the health check endpoint; scheme, host and keycloak_quarkus_http_relative_path will be prepended automatically | `realms/master/.well-known/openid-configuration` | @@ -117,7 +119,8 @@ Role Defaults |:---------|:------------|:--------| |`keycloak_quarkus_http_relative_path`| Set the path relative to / for serving resources. The path must start with a / | `/` | |`keycloak_quarkus_hostname_strict`| Disables dynamically resolving the hostname from request headers | `true` | -|`keycloak_quarkus_hostname_strict_backchannel`| By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled. | `false` | +|`keycloak_quarkus_hostname_backchannel_dynamic`| Enables dynamic resolving of backchannel URLs, including hostname, scheme, port and context path. Set to true if your application accesses Keycloak via a private network. If set to true, hostname option needs to be specified as a full URL. | `false` | +|`keycloak_quarkus_hostname_strict_backchannel`| Deprecated, use (the inverted!)`keycloak_quarkus_hostname_backchannel_dynamic` instead. | | #### Database configuration @@ -157,7 +160,6 @@ Role Defaults |`keycloak_quarkus_master_realm` | Name for rest authentication realm | `master` | |`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` | |`keycloak_force_install` | Remove pre-existing versions of service | `False` | -|`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_quarkus_host }}:{{ keycloak_http_port }}` | |`keycloak_quarkus_log`| Enable one or more log handlers in a comma-separated list | `file` | |`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` | |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index f425396..805b102 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -33,9 +33,6 @@ keycloak_quarkus_master_realm: master ### Configuration settings keycloak_quarkus_bind_address: 0.0.0.0 -keycloak_quarkus_host: localhost -keycloak_quarkus_port: -1 -keycloak_quarkus_path: keycloak_quarkus_http_enabled: true keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 @@ -81,8 +78,8 @@ keycloak_quarkus_systemd_wait_for_timeout: 60 keycloak_quarkus_systemd_wait_for_delay: 10 ### keycloak frontend url -keycloak_quarkus_frontend_url: -keycloak_quarkus_admin_url: +keycloak_quarkus_hostname: +keycloak_quarkus_admin: ### Set the path relative to / for serving resources. The path must start with a / ### (set to `/auth` for retrocompatibility with pre-quarkus releases) @@ -91,9 +88,9 @@ keycloak_quarkus_http_relative_path: / # Disables dynamically resolving the hostname from request headers. # Should always be set to true in production, unless proxy verifies the Host header. keycloak_quarkus_hostname_strict: true -# By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. -# If all applications use the public URL this option should be enabled. -keycloak_quarkus_hostname_strict_backchannel: false +# Enables dynamic resolving of backchannel URLs, including hostname, scheme, port and context path. +# Set to true if your application accesses Keycloak via a private network. If set to true, keycloak_quarkus_hostname option needs to be specified as a full URL. +keycloak_quarkus_hostname_backchannel_dynamic: false # The proxy headers that should be accepted by the server. ['', 'forwarded', 'xforwarded'] keycloak_quarkus_proxy_headers: "" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index f91bc90..b7a9ffe 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -84,17 +84,19 @@ argument_specs: default: "0.0.0.0" description: "Address for binding service ports" type: "str" + keycloak_quarkus_hostname: + description: >- + Address at which is the server exposed. + Can be a full URL, or just a hostname. When only hostname is provided, scheme, port and context path are resolved from the request. + type: "str" keycloak_quarkus_host: - default: "localhost" - description: "Hostname for the Keycloak server" + description: "Deprecated in v26, use keycloak_quarkus_hostname instead." type: "str" keycloak_quarkus_port: - default: -1 - description: "The port used by the proxy when exposing the hostname" + description: "Deprecated in v26, use keycloak_quarkus_hostname instead." type: "int" keycloak_quarkus_path: - required: false - description: "This should be set if proxy uses a different context-path for Keycloak" + description: "Deprecated in v26, use keycloak_quarkus_hostname instead." type: "str" keycloak_quarkus_http_enabled: default: true @@ -228,11 +230,15 @@ argument_specs: type: "str" keycloak_quarkus_frontend_url: required: false - description: "Service public URL" + description: "Deprecated in v26, use keycloak_quarkus_hostname instead." + type: "str" + keycloak_quarkus_admin: + required: false + description: "Service URL for the admin console" type: "str" keycloak_quarkus_admin_url: required: false - description: "Service URL for the admin console" + description: "Deprecated in v26, use keycloak_quarkus_admin instead." type: "str" keycloak_quarkus_metrics_enabled: default: false @@ -348,24 +354,18 @@ argument_specs: description: > Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless proxy verifies the Host header. - keycloak_quarkus_hostname_strict_backchannel: + keycloak_quarkus_hostname_backchannel_dynamic: default: false type: "bool" description: > - By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all - applications use the public URL this option should be enabled. + Enables dynamic resolving of backchannel URLs, including hostname, scheme, port and context path. + Set to true if your application accesses Keycloak via a private network. If set to true, hostname option needs to be specified as a full URL. keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: default: true type: "bool" description: > If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy - keycloak_quarkus_hostname_strict_https: - type: "bool" - required: false - description: > - By default, Keycloak requires running using TLS/HTTPS. If the service MUST run without TLS/HTTPS, then set - this option to "true" keycloak_quarkus_ks_vault_enabled: default: false type: "bool" diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 24972c3..c535738 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -10,13 +10,6 @@ db-password={{ keycloak_quarkus_db_pass }} {% endif %} {% endif %} -{% if keycloak_quarkus_hostname_strict_https is defined and keycloak_quarkus_hostname_strict_https is sameas true -%} -hostname-strict-https=true -{% endif -%} -{% if keycloak_quarkus_hostname_strict_https is defined and keycloak_quarkus_hostname_strict_https is sameas false -%} -hostname-strict-https=false -{% endif -%} - {% if keycloak.config_key_store_enabled %} # Config store config-keystore={{ keycloak_quarkus_config_key_store_file }} @@ -48,16 +41,10 @@ https-trust-store-password={{ keycloak_quarkus_https_trust_store_password }} {% endif %} # Client URL configuration -{% if keycloak_quarkus_frontend_url %} -hostname-url={{ keycloak_quarkus_frontend_url }} -{% else %} -hostname={{ keycloak_quarkus_host }} -hostname-port={{ keycloak_quarkus_port }} -hostname-path={{ keycloak_quarkus_path }} -{% endif %} -hostname-admin-url={{ keycloak_quarkus_admin_url }} +hostname={{ keycloak_quarkus_hostname }} +hostname-admin={{ keycloak_quarkus_admin }} hostname-strict={{ keycloak_quarkus_hostname_strict | lower }} -hostname-strict-backchannel={{ keycloak_quarkus_hostname_strict_backchannel | lower }} +hostname-backchannel-dynamic={{ keycloak_quarkus_hostname_backchannel_dynamic | lower }} # Cluster {% if keycloak_quarkus_ha_enabled %} diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index e59af55..eb654f2 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,7 +4,7 @@ keycloak: # noqa var-naming this is an internal dict of interpolated values config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "{{ 'https' if keycloak_quarkus_http_enabled == False else 'http' }}://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_https_port if keycloak_quarkus_http_enabled == False else keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' \ + health_url: "{{ keycloak_quarkus_hostname }}{{ keycloak_quarkus_http_relative_path }}{{ '/' \ if keycloak_quarkus_http_relative_path | length > 1 else '' }}{{ keycloak_quarkus_health_check_url_path | default('realms/master/.well-known/openid-configuration') }}" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" From d0f19b59dc326951b24a7909822e1689ae9fb79e Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 10 Dec 2024 14:14:18 +0100 Subject: [PATCH 328/376] keycloak_quarkus: Add http_management_port and http_management_relative_path options RHBK v26 exposes health endpoints and metrics on this port moving forward. Note that the scheme of the MGMT interface is defined by the overall keycloak configuration: if https is enabled and configured, th MGMT interface is exposed via https and NOT via http; this might be breaking some configured load balancer health checks --- roles/keycloak_quarkus/README.md | 4 +++- roles/keycloak_quarkus/defaults/main.yml | 1 + roles/keycloak_quarkus/meta/argument_specs.yml | 12 ++++++++++-- roles/keycloak_quarkus/tasks/firewalld.yml | 13 ++++++++++++- roles/keycloak_quarkus/tasks/prereqs.yml | 11 ++++++++++- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 8 ++++++++ 6 files changed, 44 insertions(+), 5 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 7f0542a..0c8aec8 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -52,6 +52,7 @@ Role Defaults |`keycloak_quarkus_path`| Deprecated, use `keycloak_quarkus_hostname` instead. | | |`keycloak_quarkus_http_port`| HTTP listening port | `8080` | |`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | +|`keycloak_quarkus_http_management_port`| Port of the management interface. Relevant only when something is exposed on the management interface - see the guide for details. | `9000` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` | @@ -69,6 +70,7 @@ Role Defaults |`keycloak_quarkus_admin`| Set the base URL for accessing the administration console, including scheme, host, port and path | | |`keycloak_quarkus_admin_url`| Deprecated, use `keycloak_quarkus_admin` instead. | | |`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | +|`keycloak_quarkus_http_management_relative_path` | Set the path relative to / for serving resources from management interface. The path must start with a /. If not given, the value is inherited from HTTP options. Relevant only when something is exposed on the management interface - see the guide for details. | `/` | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | |`keycloak_quarkus_health_check_url_path`| Path to the health check endpoint; scheme, host and keycloak_quarkus_http_relative_path will be prepended automatically | `realms/master/.well-known/openid-configuration` | |`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` | @@ -152,7 +154,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| |`keycloak_quarkus_metrics_enabled`| Whether to enable metrics | `False` | -|`keycloak_quarkus_health_enabled`| If the server should expose health check endpoints | `True` | +|`keycloak_quarkus_health_enabled`| If the server should expose health check endpoints on the management interface | `True` | |`keycloak_quarkus_archive` | keycloak install archive filename | `keycloak-{{ keycloak_quarkus_version }}.zip` | |`keycloak_quarkus_installdir` | Installation path | `{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}` | |`keycloak_quarkus_home` | Installation work directory | `{{ keycloak_quarkus_installdir }}` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 805b102..05e0455 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -36,6 +36,7 @@ keycloak_quarkus_bind_address: 0.0.0.0 keycloak_quarkus_http_enabled: true keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 +keycloak_quarkus_http_management_port: 9000 keycloak_quarkus_ajp_port: 8009 keycloak_quarkus_jgroups_port: 7800 keycloak_quarkus_java_heap_opts: "-Xms1024m -Xmx2048m" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index b7a9ffe..2bfbf50 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -108,7 +108,7 @@ argument_specs: type: "int" keycloak_quarkus_health_check_url_path: default: "realms/master/.well-known/openid-configuration" - description: "Path to the health check endpoint; scheme, host and keycloak_quarkus_http_relative_path will be prepended automatically" + description: "Path to the health check endpoint; scheme, hostname will be prepended automatically" type: "str" keycloak_quarkus_https_key_file_enabled: default: false @@ -184,6 +184,10 @@ argument_specs: default: 8443 description: "HTTPS port" type: "int" + keycloak_quarkus_http_management_port: + default: 9000 + description: "Port of the management interface. Relevant only when something is exposed on the management interface - see the guide for details." + type: "int" keycloak_quarkus_ajp_port: default: 8009 description: "AJP port" @@ -228,6 +232,10 @@ argument_specs: default: / description: "Set the path relative to / for serving resources. The path must start with a /" type: "str" + keycloak_quarkus_http_management_relative_path: + required: false + description: "Set the path relative to / for serving resources from management interface. The path must start with a /. If not given, the value is inherited from HTTP options. Relevant only when something is exposed on the management interface - see the guide for details." + type: "str" keycloak_quarkus_frontend_url: required: false description: "Deprecated in v26, use keycloak_quarkus_hostname instead." @@ -246,7 +254,7 @@ argument_specs: type: "bool" keycloak_quarkus_health_enabled: default: true - description: "If the server should expose health check endpoints" + description: "If the server should expose health check endpoints on the management interface" type: "bool" keycloak_quarkus_ispn_user: default: "supervisor" diff --git a/roles/keycloak_quarkus/tasks/firewalld.yml b/roles/keycloak_quarkus/tasks/firewalld.yml index 2c3ef74..2d48124 100644 --- a/roles/keycloak_quarkus/tasks/firewalld.yml +++ b/roles/keycloak_quarkus/tasks/firewalld.yml @@ -12,7 +12,7 @@ enabled: true state: started -- name: "Configure firewall for {{ keycloak.service_name }} ports" +- name: "Configure firewall for {{ keycloak.service_name }} http port" become: true ansible.posix.firewalld: port: "{{ item }}" @@ -21,5 +21,16 @@ immediate: true loop: - "{{ keycloak_quarkus_http_port }}/tcp" + when: keycloak_quarkus_http_enabled | bool + +- name: "Configure firewall for {{ keycloak.service_name }} ports" + become: true + ansible.posix.firewalld: + port: "{{ item }}" + permanent: true + state: enabled + immediate: true + loop: - "{{ keycloak_quarkus_https_port }}/tcp" + - "{{ keycloak_quarkus_http_management_port }}/tcp" - "{{ keycloak_quarkus_jgroups_port }}/tcp" diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index db7555e..9b633f3 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -7,7 +7,7 @@ fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_bootstrap_admin_password to a 12+ char long string" success_msg: "{{ 'Console administrator password OK' }}" -- name: Validate relative path +- name: Validate http_relative_path ansible.builtin.assert: that: - keycloak_quarkus_http_relative_path is regex('^/.*') @@ -15,6 +15,15 @@ fail_msg: "The relative path for keycloak_quarkus_http_relative_path must begin with /" success_msg: "{{ 'Relative path OK' }}" +- name: Validate http_management_relative_path + ansible.builtin.assert: + that: + - keycloak_quarkus_http_management_relative_path is regex('^/.*') + quiet: true + fail_msg: "The relative path for keycloak_quarkus_http_management_relative_path must begin with /" + success_msg: "{{ 'Relative mgmt path OK' }}" + when: keycloak_quarkus_http_management_relative_path is defined + - name: Validate configuration ansible.builtin.assert: that: diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index c535738..f11e3ec 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -22,9 +22,17 @@ health-enabled={{ keycloak_quarkus_health_enabled | lower }} # HTTP http-enabled={{ keycloak_quarkus_http_enabled | lower }} +{% if keycloak_quarkus_http_enabled %} http-port={{ keycloak_quarkus_http_port }} +{% endif %} http-relative-path={{ keycloak_quarkus_http_relative_path }} +# Management +http-management-port={{ keycloak_quarkus_http_management_port }} +{% if keycloak_quarkus_http_management_relative_path is defined and keycloak_quarkus_http_management_relative_path | length > 0 %} +http-management-relative-path={{ keycloak_quarkus_http_management_relative_path }} +{% endif %} + # HTTPS https-port={{ keycloak_quarkus_https_port }} {% if keycloak_quarkus_https_key_file_enabled %} From e029e1c2fd0d86d765e824d78cb6c348f28efc8e Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Fri, 13 Dec 2024 12:02:06 +0100 Subject: [PATCH 329/376] keycloak_quarkus: Introduce keycloak_quarkus_health_check_url --- roles/keycloak_quarkus/README.md | 3 ++- roles/keycloak_quarkus/meta/argument_specs.yml | 5 ++++- roles/keycloak_quarkus/vars/main.yml | 3 +-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 0c8aec8..d3abd57 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -72,7 +72,8 @@ Role Defaults |`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | |`keycloak_quarkus_http_management_relative_path` | Set the path relative to / for serving resources from management interface. The path must start with a /. If not given, the value is inherited from HTTP options. Relevant only when something is exposed on the management interface - see the guide for details. | `/` | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | -|`keycloak_quarkus_health_check_url_path`| Path to the health check endpoint; scheme, host and keycloak_quarkus_http_relative_path will be prepended automatically | `realms/master/.well-known/openid-configuration` | +|`keycloak_quarkus_health_check_url`| Full URL (including scheme, host, path, fragment etc.) used for health check endpoint; keycloak_quarkus_hostname will NOT be prepended; helpful when health checks should happen against http port, but keycloak_quarkus_hostname uses https scheme per default | `` | +|`keycloak_quarkus_health_check_url_path`| Path to the health check endpoint; keycloak_quarkus_hostname will be prepended automatically; Note that keycloak_quarkus_health_check_url takes precedence over this property | `realms/master/.well-known/openid-configuration` | |`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` | |`keycloak_quarkus_key_file_copy_enabled`| Enable copy of key file to target host | `False` | |`keycloak_quarkus_key_content`| Content of the TLS private key. Use `"{{ lookup('file', 'server.key.pem') }}"` to lookup a file. | `""` | diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 2bfbf50..0e4eb42 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -106,9 +106,12 @@ argument_specs: default: 8080 description: "HTTP port" type: "int" + keycloak_quarkus_health_check_url: + description: "Full URL (including scheme, host, path, fragment etc.) used for health check endpoint; keycloak_quarkus_hostname will NOT be prepended; helpful when health checks should happen against http port, but keycloak_quarkus_hostname uses https scheme per default" + type: "str" keycloak_quarkus_health_check_url_path: default: "realms/master/.well-known/openid-configuration" - description: "Path to the health check endpoint; scheme, hostname will be prepended automatically" + description: "Path to the health check endpoint; keycloak_quarkus_hostname will be prepended automatically; Note that keycloak_quarkus_health_check_url takes precedence over this property" type: "str" keycloak_quarkus_https_key_file_enabled: default: false diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index eb654f2..2efe5e6 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,8 +4,7 @@ keycloak: # noqa var-naming this is an internal dict of interpolated values config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "{{ keycloak_quarkus_hostname }}{{ keycloak_quarkus_http_relative_path }}{{ '/' \ - if keycloak_quarkus_http_relative_path | length > 1 else '' }}{{ keycloak_quarkus_health_check_url_path | default('realms/master/.well-known/openid-configuration') }}" + health_url: "{{ keycloak_quarkus_health_check_url | default(keycloak_quarkus_hostname + '/' + (keycloak_quarkus_health_check_url_path | default('realms/master/.well-known/openid-configuration'))) }}" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" From b3e93dd89b8506d3a6f283491987286d15c5185b Mon Sep 17 00:00:00 2001 From: Nils Deckert Date: Fri, 20 Dec 2024 17:21:01 +0100 Subject: [PATCH 330/376] Skip certificate checking --- roles/keycloak_realm/tasks/main.yml | 1 + roles/keycloak_realm/tasks/manage_user_client_roles.yml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index 8f33fcc..7595ba3 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -15,6 +15,7 @@ ansible.builtin.uri: url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}" method: GET + validate_certs: false status_code: - 200 - 404 diff --git a/roles/keycloak_realm/tasks/manage_user_client_roles.yml b/roles/keycloak_realm/tasks/manage_user_client_roles.yml index 3884f42..f9e0329 100644 --- a/roles/keycloak_realm/tasks/manage_user_client_roles.yml +++ b/roles/keycloak_realm/tasks/manage_user_client_roles.yml @@ -3,6 +3,7 @@ ansible.builtin.uri: url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | default(keycloak_realm) }}" method: GET + validate_certs: false status_code: - 200 headers: @@ -16,6 +17,7 @@ default(keycloak_realm) }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | \ selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}/available" method: GET + validate_certs: false status_code: - 200 headers: From 86284b12c28f578910ecd3cd200cab9679b6d8ee Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 10 Dec 2024 15:10:29 +0100 Subject: [PATCH 331/376] Fix molecule tests --- molecule/debian/converge.yml | 5 ++++- molecule/debian/prepare.yml | 1 + molecule/default/converge.yml | 5 ++++- molecule/default/molecule.yml | 1 + molecule/default/prepare.yml | 2 +- molecule/default/verify.yml | 3 ++- molecule/https_revproxy/converge.yml | 5 ++--- molecule/overridexml/molecule.yml | 1 + molecule/quarkus-devmode/converge.yml | 5 ++++- molecule/quarkus-devmode/molecule.yml | 2 ++ molecule/quarkus/converge.yml | 7 +++++-- molecule/quarkus/molecule.yml | 1 + molecule/quarkus/prepare.yml | 2 +- molecule/quarkus/verify.yml | 13 +++++++------ molecule/quarkus_ha/converge.yml | 3 +-- molecule/quarkus_ha/molecule.yml | 2 ++ molecule/quarkus_upgrade/converge.yml | 2 +- molecule/quarkus_upgrade/molecule.yml | 2 ++ molecule/quarkus_upgrade/prepare.yml | 2 +- molecule/quarkus_upgrade/vars.yml | 2 +- molecule/quarkus_upgrade/verify.yml | 2 +- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++-- roles/keycloak_quarkus/vars/redhat.yml | 2 +- 24 files changed, 49 insertions(+), 27 deletions(-) diff --git a/molecule/debian/converge.yml b/molecule/debian/converge.yml index 7fab040..e853b38 100644 --- a/molecule/debian/converge.yml +++ b/molecule/debian/converge.yml @@ -5,14 +5,17 @@ keycloak_quarkus_show_deprecation_warnings: false keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" - keycloak_quarkus_hostname: http://instance + keycloak_quarkus_hostname: http://instance:8080 keycloak_quarkus_log: file keycloak_quarkus_start_dev: true keycloak_quarkus_proxy_mode: none roles: - role: keycloak_quarkus - role: keycloak_realm + keycloak_url: "{{ keycloak_quarkus_hostname }}" keycloak_context: '' + keycloak_admin_user: "{{ keycloak_quarkus_bootstrap_admin_user }}" + keycloak_admin_password: "{{ keycloak_quarkus_bootstrap_admin_password }}" keycloak_client_users: - username: TestUser password: password diff --git a/molecule/debian/prepare.yml b/molecule/debian/prepare.yml index 6025ef9..267386e 100644 --- a/molecule/debian/prepare.yml +++ b/molecule/debian/prepare.yml @@ -7,5 +7,6 @@ ansible.builtin.apt: name: - sudo + # - openjdk-21-jdk-headless # this is not available in ghcr.io/hspaans/molecule-containers:debian-11 (neither in debian-12) since the images are using outdated package sources - openjdk-17-jdk-headless state: present diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index 13a771b..de97748 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -5,7 +5,7 @@ keycloak_quarkus_show_deprecation_warnings: false keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" - keycloak_quarkus_hostname: http://instance + keycloak_quarkus_hostname: http://instance:8080 keycloak_quarkus_log: file keycloak_quarkus_log_level: debug keycloak_quarkus_log_target: /tmp/keycloak @@ -16,7 +16,10 @@ roles: - role: keycloak_quarkus - role: keycloak_realm + keycloak_url: "{{ keycloak_quarkus_hostname }}" keycloak_context: '' + keycloak_admin_user: "{{ keycloak_quarkus_bootstrap_admin_user }}" + keycloak_admin_password: "{{ keycloak_quarkus_bootstrap_admin_password }}" keycloak_client_users: - username: TestUser password: password diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index c133eee..62fa2b7 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -11,6 +11,7 @@ platforms: - "8080/tcp" - "8443/tcp" - "8009/tcp" + - "9000/tcp" provisioner: name: ansible config_options: diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index 899dabd..eefd5cf 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -22,7 +22,7 @@ - name: Download keycloak archive to controller directory ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user - url: https://github.com/keycloak/keycloak/releases/download/24.0.5/keycloak-24.0.5.zip + url: https://github.com/keycloak/keycloak/releases/download/26.0.7/keycloak-26.0.7.zip dest: /tmp/keycloak mode: '0640' delegate_to: localhost diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index eac4339..ae21396 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -2,6 +2,7 @@ - name: Verify hosts: all vars: + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_uri: "http://localhost:8080" tasks: @@ -16,7 +17,7 @@ ansible.builtin.uri: url: "{{ keycloak_uri }}/realms/master/protocol/openid-connect/token" method: POST - body: "client_id=admin-cli&username=admin&password={{ keycloak_quarkus_bootstrap_admin_user }}&grant_type=password" + body: "client_id=admin-cli&username={{ keycloak_quarkus_bootstrap_admin_user }}&password={{ keycloak_quarkus_bootstrap_admin_user }}&grant_type=password" validate_certs: no register: keycloak_auth_response until: keycloak_auth_response.status == 200 diff --git a/molecule/https_revproxy/converge.yml b/molecule/https_revproxy/converge.yml index 7245265..92994fa 100644 --- a/molecule/https_revproxy/converge.yml +++ b/molecule/https_revproxy/converge.yml @@ -5,13 +5,12 @@ keycloak_quarkus_show_deprecation_warnings: false keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" - keycloak_realm: TestRealm - keycloak_quarkus_hostname: http://instance + keycloak_quarkus_hostname: https://proxy keycloak_quarkus_log: file keycloak_quarkus_http_enabled: True keycloak_quarkus_http_port: 8080 keycloak_quarkus_proxy_mode: edge keycloak_quarkus_http_relative_path: / - keycloak_quarkus_frontend_url: https://proxy/ + keycloak_quarkus_health_check_url: http://proxy:8080/realms/master/.well-known/openid-configuration roles: - role: keycloak_quarkus diff --git a/molecule/overridexml/molecule.yml b/molecule/overridexml/molecule.yml index c133eee..62fa2b7 100644 --- a/molecule/overridexml/molecule.yml +++ b/molecule/overridexml/molecule.yml @@ -11,6 +11,7 @@ platforms: - "8080/tcp" - "8443/tcp" - "8009/tcp" + - "9000/tcp" provisioner: name: ansible config_options: diff --git a/molecule/quarkus-devmode/converge.yml b/molecule/quarkus-devmode/converge.yml index 5cd4ea1..6c0b14f 100644 --- a/molecule/quarkus-devmode/converge.yml +++ b/molecule/quarkus-devmode/converge.yml @@ -7,14 +7,17 @@ keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_realm: TestRealm keycloak_quarkus_log: file - keycloak_quarkus_frontend_url: 'http://localhost:8080/' + keycloak_quarkus_hostname: 'http://localhost:8080' keycloak_quarkus_start_dev: True keycloak_quarkus_proxy_mode: none keycloak_quarkus_java_home: /opt/openjdk/ roles: - role: keycloak_quarkus - role: keycloak_realm + keycloak_url: "{{ keycloak_quarkus_hostname }}" keycloak_context: '' + keycloak_admin_user: "{{ keycloak_quarkus_bootstrap_admin_user }}" + keycloak_admin_password: "{{ keycloak_quarkus_bootstrap_admin_password }}" keycloak_client_default_roles: - TestRoleAdmin - TestRoleUser diff --git a/molecule/quarkus-devmode/molecule.yml b/molecule/quarkus-devmode/molecule.yml index 191234d..5d22ab8 100644 --- a/molecule/quarkus-devmode/molecule.yml +++ b/molecule/quarkus-devmode/molecule.yml @@ -10,8 +10,10 @@ platforms: port_bindings: - "8080/tcp" - "8009/tcp" + - "9000/tcp" published_ports: - 0.0.0.0:8080:8080/tcp + - 0.0.0.0:9000:9000/TCP provisioner: name: ansible config_options: diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 9b7b3a7..9bfbc0f 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -6,7 +6,7 @@ keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_realm: TestRealm - keycloak_quarkus_hostname: http://instance + keycloak_quarkus_hostname: https://instance:8443 keycloak_quarkus_log: file keycloak_quarkus_log_level: debug # needed for the verify step keycloak_quarkus_https_key_file_enabled: true @@ -37,7 +37,7 @@ repository_url: https://repo1.maven.org/maven2/ # https://mvnrepository.com/artifact/org.keycloak/keycloak-kerberos-federation/24.0.4 group_id: org.keycloak artifact_id: keycloak-kerberos-federation - version: 24.0.5 # optional + version: 26.0.7 # optional # username: myUser # optional # password: myPAT # optional # - id: my-static-theme @@ -51,7 +51,10 @@ roles: - role: keycloak_quarkus - role: keycloak_realm + keycloak_url: "{{ keycloak_quarkus_hostname }}" keycloak_context: '' + keycloak_admin_user: "{{ keycloak_quarkus_bootstrap_admin_user }}" + keycloak_admin_password: "{{ keycloak_quarkus_bootstrap_admin_password }}" keycloak_client_default_roles: - TestRoleAdmin - TestRoleUser diff --git a/molecule/quarkus/molecule.yml b/molecule/quarkus/molecule.yml index c04e300..c083e77 100644 --- a/molecule/quarkus/molecule.yml +++ b/molecule/quarkus/molecule.yml @@ -11,6 +11,7 @@ platforms: - "8080/tcp" - "8443/tcp" - "8009/tcp" + - "9000/tcp" published_ports: - 0.0.0.0:8443:8443/tcp provisioner: diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 21a0f30..d8ef369 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -24,7 +24,7 @@ - name: Make sure a jre is available (for keytool to prepare keystore) delegate_to: localhost ansible.builtin.package: - name: "{{ 'java-17-openjdk-headless' if hera_home | length > 0 else 'openjdk-17-jdk-headless' }}" + name: "{{ 'java-21-openjdk-headless' if hera_home | length > 0 else 'openjdk-21-jdk-headless' }}" state: present become: true failed_when: false diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 1ee3b61..f041d88 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -2,7 +2,8 @@ - name: Verify hosts: all vars: - keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" tasks: - name: Populate service facts ansible.builtin.service_facts: @@ -35,10 +36,10 @@ - name: Verify endpoint URLs ansible.builtin.assert: that: - - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://instance/realms/master/protocol/openid-connect/ext/ciba/auth' - - (openid_config.stdout | from_json)['issuer'] == 'https://instance/realms/master' - - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/auth' - - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/token' + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://instance:8443/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'https://instance:8443/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance:8443/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance:8443/realms/master/protocol/openid-connect/token' delegate_to: localhost - name: Check log folder @@ -91,7 +92,7 @@ ansible.builtin.uri: url: "https://instance:8443/realms/master/protocol/openid-connect/token" method: POST - body: "client_id=admin-cli&username=admin&password={{ keycloak_quarkus_bootstrap_admin_user }}&grant_type=password" + body: "client_id=admin-cli&username={{ keycloak_quarkus_bootstrap_admin_user }}&password={{ keycloak_quarkus_bootstrap_admin_password}}&grant_type=password" validate_certs: no register: keycloak_auth_response until: keycloak_auth_response.status == 200 diff --git a/molecule/quarkus_ha/converge.yml b/molecule/quarkus_ha/converge.yml index 238fbb5..d37ad79 100644 --- a/molecule/quarkus_ha/converge.yml +++ b/molecule/quarkus_ha/converge.yml @@ -5,8 +5,7 @@ keycloak_quarkus_show_deprecation_warnings: false keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" - keycloak_realm: TestRealm - keycloak_quarkus_hostname: "http://{{ inventory_hostname }}" + keycloak_quarkus_hostname: "http://{{ inventory_hostname }}:8080" keycloak_quarkus_log: file keycloak_quarkus_log_level: info keycloak_quarkus_https_key_file_enabled: true diff --git a/molecule/quarkus_ha/molecule.yml b/molecule/quarkus_ha/molecule.yml index 8e07e0f..43a8286 100644 --- a/molecule/quarkus_ha/molecule.yml +++ b/molecule/quarkus_ha/molecule.yml @@ -14,6 +14,7 @@ platforms: port_bindings: - "8080/tcp" - "8443/tcp" + - "9000/tcp" - name: instance2 image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true @@ -26,6 +27,7 @@ platforms: port_bindings: - "8080/tcp" - "8443/tcp" + - "9000/tcp" - name: postgres image: ubuntu/postgres:14-22.04_beta pre_build_image: true diff --git a/molecule/quarkus_upgrade/converge.yml b/molecule/quarkus_upgrade/converge.yml index 6025b7c..9b57436 100644 --- a/molecule/quarkus_upgrade/converge.yml +++ b/molecule/quarkus_upgrade/converge.yml @@ -5,6 +5,6 @@ - vars.yml vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_version: 24.0.3 + keycloak_quarkus_version: 26.0.7 roles: - role: keycloak_quarkus diff --git a/molecule/quarkus_upgrade/molecule.yml b/molecule/quarkus_upgrade/molecule.yml index 77f687f..21782e8 100644 --- a/molecule/quarkus_upgrade/molecule.yml +++ b/molecule/quarkus_upgrade/molecule.yml @@ -13,8 +13,10 @@ platforms: privileged: true port_bindings: - 8080:8080 + - "9000/tcp" published_ports: - 0.0.0.0:8080:8080/TCP + - 0.0.0.0:9000:9000/TCP provisioner: name: ansible playbooks: diff --git a/molecule/quarkus_upgrade/prepare.yml b/molecule/quarkus_upgrade/prepare.yml index bebfc68..a6892e3 100644 --- a/molecule/quarkus_upgrade/prepare.yml +++ b/molecule/quarkus_upgrade/prepare.yml @@ -5,7 +5,7 @@ - vars.yml vars: sudo_pkg_name: sudo - keycloak_quarkus_version: 23.0.7 + keycloak_quarkus_version: 24.0.5 pre_tasks: - name: Install sudo ansible.builtin.apt: diff --git a/molecule/quarkus_upgrade/vars.yml b/molecule/quarkus_upgrade/vars.yml index 52ab103..1567ae4 100644 --- a/molecule/quarkus_upgrade/vars.yml +++ b/molecule/quarkus_upgrade/vars.yml @@ -2,7 +2,7 @@ keycloak_quarkus_offline_install: false keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_realm: TestRealm -keycloak_quarkus_hostname: http://instance +keycloak_quarkus_hostname: http://instance:8080 keycloak_quarkus_log: file keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_log_target: /tmp/keycloak diff --git a/molecule/quarkus_upgrade/verify.yml b/molecule/quarkus_upgrade/verify.yml index 3214d9f..1c4a0ba 100644 --- a/molecule/quarkus_upgrade/verify.yml +++ b/molecule/quarkus_upgrade/verify.yml @@ -17,7 +17,7 @@ - name: Verify we are running on requested jvm ansible.builtin.shell: | set -eo pipefail - ps -ef | grep 'etc/alternatives/.*17' | grep -v grep + ps -ef | grep 'etc/alternatives/.*21' | grep -v grep changed_when: false - name: Verify token api call diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index d3abd57..bafc150 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -59,7 +59,7 @@ Role Defaults |`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` | |`keycloak_quarkus_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` | |`keycloak_quarkus_service_restartsec`| systemd RestartSec | `10s` | -|`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | +|`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-21-openjdk-headless` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | |`keycloak_quarkus_java_heap_opts`| Heap memory JVM setting | `-Xms1024m -Xmx2048m` | |`keycloak_quarkus_java_jvm_opts`| Other JVM settings | same as keycloak | diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 0e4eb42..3eaf5d4 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -22,7 +22,7 @@ argument_specs: description: "Perform an offline install" type: "bool" keycloak_quarkus_jvm_package: - default: "java-11-openjdk-headless" + default: "java-21-openjdk-headless" description: "RHEL java package runtime" type: "str" keycloak_quarkus_java_home: @@ -479,7 +479,7 @@ argument_specs: downstream: options: rhbk_version: - default: "26.0.6" + default: "26.0.7" description: "Red Hat Build of Keycloak version" type: "str" rhbk_archive: diff --git a/roles/keycloak_quarkus/vars/redhat.yml b/roles/keycloak_quarkus/vars/redhat.yml index c311321..9af167f 100644 --- a/roles/keycloak_quarkus/vars/redhat.yml +++ b/roles/keycloak_quarkus/vars/redhat.yml @@ -1,5 +1,5 @@ --- -keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('java-17-openjdk-headless') }}" +keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('java-21-openjdk-headless') }}" keycloak_quarkus_prereq_package_list: - "{{ keycloak_quarkus_varjvm_package }}" - unzip From fa367212079a9d55e13013fba22cb64ac28fd5a2 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 20 Jan 2025 09:44:27 +0100 Subject: [PATCH 332/376] Improve string interpolation --- roles/keycloak_quarkus/vars/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index 2efe5e6..997d7dc 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,7 +4,7 @@ keycloak: # noqa var-naming this is an internal dict of interpolated values config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "{{ keycloak_quarkus_health_check_url | default(keycloak_quarkus_hostname + '/' + (keycloak_quarkus_health_check_url_path | default('realms/master/.well-known/openid-configuration'))) }}" + health_url: "{{ keycloak_quarkus_health_check_url | default(keycloak_quarkus_hostname ~ '/' ~ (keycloak_quarkus_health_check_url_path | default('realms/master/.well-known/openid-configuration'))) }}" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" From 5db96afa56a589b445fc2481c08b1fad57e0fdb6 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 1 Apr 2025 15:20:37 +0200 Subject: [PATCH 333/376] Variables names must not be Ansible reserved names --- roles/keycloak/tasks/rhsso_cli.yml | 6 +++--- roles/keycloak/tasks/rhsso_patch.yml | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/roles/keycloak/tasks/rhsso_cli.yml b/roles/keycloak/tasks/rhsso_cli.yml index fd41dd6..e40dec8 100644 --- a/roles/keycloak/tasks/rhsso_cli.yml +++ b/roles/keycloak/tasks/rhsso_cli.yml @@ -2,12 +2,12 @@ - name: Ensure required params for CLI have been provided ansible.builtin.assert: that: - - query is defined + - cli_query is defined fail_msg: "Missing required parameters to execute CLI." quiet: true -- name: "Execute CLI query: {{ query }}" +- name: "Execute CLI query: {{ cli_query }}" ansible.builtin.command: > - {{ keycloak.cli_path }} --connect --command='{{ query }}' --controller={{ keycloak_host }}:{{ keycloak_management_http_port }} + {{ keycloak.cli_path }} --connect --command='{{ cli_query }}' --controller={{ keycloak_host }}:{{ keycloak_management_http_port }} changed_when: false register: cli_result diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index e7ac3f0..23d75bf 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -106,7 +106,7 @@ - name: "Check installed patches" ansible.builtin.include_tasks: rhsso_cli.yml vars: - query: "patch info" + cli_query: "patch info" args: apply: become: true @@ -121,7 +121,7 @@ - name: "Apply patch {{ patch_version }} to server" ansible.builtin.include_tasks: rhsso_cli.yml vars: - query: "patch apply {{ patch_archive }}" + cli_query: "patch apply {{ patch_archive }}" args: apply: become: true @@ -130,7 +130,7 @@ - name: "Restart server to ensure patch content is running" ansible.builtin.include_tasks: rhsso_cli.yml vars: - query: "shutdown --restart" + cli_query: "shutdown --restart" when: - cli_result.rc == 0 args: @@ -149,7 +149,7 @@ - name: "Query installed patch after restart" ansible.builtin.include_tasks: rhsso_cli.yml vars: - query: "patch info" + cli_query: "patch info" args: apply: become: true From 7f980c44d287971c1cc4d9c899518549d2c82fa6 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 8 Apr 2025 11:58:47 +0200 Subject: [PATCH 334/376] Bump major and ansible-core versions --- CONTRIBUTING.md | 2 +- README.md | 2 +- galaxy.yml | 2 +- meta/runtime.yml | 2 +- roles/keycloak/meta/main.yml | 2 +- roles/keycloak_quarkus/meta/main.yml | 2 +- roles/keycloak_realm/meta/main.yml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 21ddc18..95b60ed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,7 @@ virtualenv $PATH_TO_DEV_VIRTUALENV # activate the virtual env source $PATH_TO_DEV_VIRTUALENV/bin/activate # install ansible and tools onto the virtualenv -pip install yamllint 'molecule>=6.0' 'molecule-plugins[docker]' 'ansible-core>=2.15' ansible-lint +pip install yamllint 'molecule>=6.0' 'molecule-plugins[docker]' 'ansible-core>=2.16' ansible-lint # install collection dependencies ansible-galaxy collection install -r requirements.yml # install python dependencies diff --git a/README.md b/README.md index e8c289e..9e9867d 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Re ## Ansible version compatibility -This collection has been tested against following Ansible versions: **>=2.15.0**. +This collection has been tested against following Ansible versions: **>=2.16.0**. Plugins and modules within a collection may be tested with only specific Ansible versions. A collection may contain metadata that identifies these versions. diff --git a/galaxy.yml b/galaxy.yml index a6511a8..76c46c4 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.4.4" +version: "3.0.0" readme: README.md authors: - Romain Pelisse diff --git a/meta/runtime.yml b/meta/runtime.yml index 1e85b01..49c7554 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1,2 +1,2 @@ --- -requires_ansible: ">=2.15.0" +requires_ansible: ">=2.16.0" diff --git a/roles/keycloak/meta/main.yml b/roles/keycloak/meta/main.yml index a27afb8..59499e6 100644 --- a/roles/keycloak/meta/main.yml +++ b/roles/keycloak/meta/main.yml @@ -12,7 +12,7 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.15" + min_ansible_version: "2.16" platforms: - name: EL diff --git a/roles/keycloak_quarkus/meta/main.yml b/roles/keycloak_quarkus/meta/main.yml index 40a487f..65b5e50 100644 --- a/roles/keycloak_quarkus/meta/main.yml +++ b/roles/keycloak_quarkus/meta/main.yml @@ -8,7 +8,7 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.15" + min_ansible_version: "2.16" platforms: - name: EL diff --git a/roles/keycloak_realm/meta/main.yml b/roles/keycloak_realm/meta/main.yml index ab861ed..97c69d2 100644 --- a/roles/keycloak_realm/meta/main.yml +++ b/roles/keycloak_realm/meta/main.yml @@ -8,7 +8,7 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.15" + min_ansible_version: "2.16" platforms: - name: EL From 744766fe3bc52a50d9e0b4729179e11c149327f1 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 8 Apr 2025 15:36:38 +0200 Subject: [PATCH 335/376] update doc generation to 2.16 --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index c8f8e2d..303f3a6 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,7 +1,7 @@ antsibull>=0.17.0 antsibull-docs antsibull-changelog -ansible-core>=2.14.1 +ansible-core>=2.16.0 ansible-pygments sphinx-rtd-theme git+https://github.com/felixfontein/ansible-basic-sphinx-ext From ac0ceca35f46fbfce135648fea88deacc0b7d45b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 9 Apr 2025 09:45:22 +0200 Subject: [PATCH 336/376] Update to ubi9 --- molecule/default/molecule.yml | 2 +- molecule/https_revproxy/molecule.yml | 4 ++-- molecule/overridexml/molecule.yml | 2 +- molecule/quarkus-devmode/molecule.yml | 2 +- molecule/quarkus/molecule.yml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index 62fa2b7..011c08e 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -3,7 +3,7 @@ driver: name: docker platforms: - name: instance - image: registry.access.redhat.com/ubi8/ubi-init:latest + image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true privileged: true command: "/usr/sbin/init" diff --git a/molecule/https_revproxy/molecule.yml b/molecule/https_revproxy/molecule.yml index 48bf375..7ad8db8 100644 --- a/molecule/https_revproxy/molecule.yml +++ b/molecule/https_revproxy/molecule.yml @@ -3,7 +3,7 @@ driver: name: docker platforms: - name: instance - image: registry.access.redhat.com/ubi8/ubi-init:latest + image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true privileged: true command: "/usr/sbin/init" @@ -14,7 +14,7 @@ platforms: published_ports: - 0.0.0.0:8080:8080/tcp - name: proxy - image: registry.access.redhat.com/ubi8/ubi-init:latest + image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true privileged: true command: "/usr/sbin/init" diff --git a/molecule/overridexml/molecule.yml b/molecule/overridexml/molecule.yml index 62fa2b7..011c08e 100644 --- a/molecule/overridexml/molecule.yml +++ b/molecule/overridexml/molecule.yml @@ -3,7 +3,7 @@ driver: name: docker platforms: - name: instance - image: registry.access.redhat.com/ubi8/ubi-init:latest + image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true privileged: true command: "/usr/sbin/init" diff --git a/molecule/quarkus-devmode/molecule.yml b/molecule/quarkus-devmode/molecule.yml index 5d22ab8..2da7e01 100644 --- a/molecule/quarkus-devmode/molecule.yml +++ b/molecule/quarkus-devmode/molecule.yml @@ -3,7 +3,7 @@ driver: name: docker platforms: - name: instance - image: registry.access.redhat.com/ubi8/ubi-init:latest + image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true privileged: true command: "/usr/sbin/init" diff --git a/molecule/quarkus/molecule.yml b/molecule/quarkus/molecule.yml index c083e77..60995cc 100644 --- a/molecule/quarkus/molecule.yml +++ b/molecule/quarkus/molecule.yml @@ -3,7 +3,7 @@ driver: name: docker platforms: - name: instance - image: registry.access.redhat.com/ubi8/ubi-init:latest + image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true privileged: true command: "/usr/sbin/init" From f628b84fb0287942c5cbd40a7776d61acfb21ea5 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 9 Apr 2025 17:21:49 +0200 Subject: [PATCH 337/376] disable restart health check because of selfsigned cert --- molecule/quarkus/converge.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 9bfbc0f..db30473 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -22,6 +22,7 @@ keycloak_quarkus_systemd_wait_for_timeout: 20 keycloak_quarkus_systemd_wait_for_delay: 2 keycloak_quarkus_systemd_wait_for_log: true + keycloak_quarkus_restart_health_check: false # would fail because of self-signed cert keycloak_quarkus_providers: - id: http-client spi: connections From 314e2f26b27d264960d72c4e235ba6c0b69f4e58 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 9 Apr 2025 17:22:22 +0200 Subject: [PATCH 338/376] Fix spell in parameter name --- molecule/quarkus/converge.yml | 2 +- molecule/quarkus/molecule.yml | 1 + molecule/quarkus/verify.yml | 8 ++++---- molecule/quarkus_ha/molecule.yml | 1 + roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- roles/keycloak_quarkus/tasks/restart.yml | 2 +- roles/keycloak_quarkus/tasks/start.yml | 1 + 9 files changed, 12 insertions(+), 9 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index db30473..b7c15e1 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -52,7 +52,7 @@ roles: - role: keycloak_quarkus - role: keycloak_realm - keycloak_url: "{{ keycloak_quarkus_hostname }}" + keycloak_url: http://instance:8080 keycloak_context: '' keycloak_admin_user: "{{ keycloak_quarkus_bootstrap_admin_user }}" keycloak_admin_password: "{{ keycloak_quarkus_bootstrap_admin_password }}" diff --git a/molecule/quarkus/molecule.yml b/molecule/quarkus/molecule.yml index 60995cc..cf975e5 100644 --- a/molecule/quarkus/molecule.yml +++ b/molecule/quarkus/molecule.yml @@ -31,6 +31,7 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" + PYTHONHTTPSVERIFY: 0 verifier: name: ansible scenario: diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index f041d88..1d9d2c3 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -102,8 +102,8 @@ - name: "Get Clients" ansible.builtin.uri: url: "https://instance:8443/admin/realms/TestRealm/clients" + validate_certs: false headers: - validate_certs: false Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" register: keycloak_clients @@ -114,15 +114,15 @@ - name: "Get Client {{ keycloak_client_uuid }}" ansible.builtin.uri: url: "https://instance:8443/admin/realms/TestRealm/clients/{{ keycloak_client_uuid }}" + validate_certs: false headers: - validate_certs: false Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" register: keycloak_test_client - name: "Get Client roles" ansible.builtin.uri: url: "https://instance:8443/admin/realms/TestRealm/clients/{{ keycloak_client_uuid }}/roles" + validate_certs: false headers: - validate_certs: false Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" - register: keycloak_test_client_roles \ No newline at end of file + register: keycloak_test_client_roles diff --git a/molecule/quarkus_ha/molecule.yml b/molecule/quarkus_ha/molecule.yml index 43a8286..ed09971 100644 --- a/molecule/quarkus_ha/molecule.yml +++ b/molecule/quarkus_ha/molecule.yml @@ -65,6 +65,7 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" + PYTHONHTTPSVERIFY: 0 verifier: name: ansible scenario: diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index bafc150..fb30ce9 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -112,7 +112,7 @@ Role Defaults |`keycloak_quarkus_restart_strategy`| Strategy task file for restarting in HA (one of provided restart/['serial.yml','none.yml','serial_then_parallel.yml']) or path to file when providing custom strategy | `restart/serial.yml` | |`keycloak_quarkus_restart_health_check`| Whether to wait for successful health check after restart | `true` | |`keycloak_quarkus_restart_health_check_delay`| Seconds to let pass before starting healch checks | `10` | -|`keycloak_quarkus_restart_health_check_reries`| Number of attempts for successful health check before failing | `25` | +|`keycloak_quarkus_restart_health_check_retries`| Number of attempts for successful health check before failing | `25` | |`keycloak_quarkus_restart_pause`| Seconds to wait between restarts in HA strategy | `15` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 05e0455..0512960 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -163,5 +163,5 @@ keycloak_quarkus_supported_policy_types: ['password-blacklists'] keycloak_quarkus_restart_strategy: restart/serial.yml keycloak_quarkus_restart_health_check: true keycloak_quarkus_restart_health_check_delay: 10 -keycloak_quarkus_restart_health_check_reries: 25 +keycloak_quarkus_restart_health_check_retries: 25 keycloak_quarkus_restart_pause: 15 diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 3eaf5d4..4a3b7c4 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -464,7 +464,7 @@ argument_specs: description: "Seconds to let pass before starting healch checks" default: 10 type: 'int' - keycloak_quarkus_restart_health_check_reries: + keycloak_quarkus_restart_health_check_retries: description: "Number of attempts for successful health check before failing" default: 25 type: 'int' diff --git a/roles/keycloak_quarkus/tasks/restart.yml b/roles/keycloak_quarkus/tasks/restart.yml index 61356d5..3aa97f6 100644 --- a/roles/keycloak_quarkus/tasks/restart.yml +++ b/roles/keycloak_quarkus/tasks/restart.yml @@ -12,7 +12,7 @@ url: "{{ keycloak.health_url }}" register: keycloak_status until: keycloak_status.status == 200 - retries: "{{ keycloak_quarkus_restart_health_check_reries }}" + retries: "{{ keycloak_quarkus_restart_health_check_retries }}" delay: "{{ keycloak_quarkus_restart_health_check_delay }}" when: internal_force_health_check | default(keycloak_quarkus_restart_health_check) diff --git a/roles/keycloak_quarkus/tasks/start.yml b/roles/keycloak_quarkus/tasks/start.yml index a640e89..5a3ad5f 100644 --- a/roles/keycloak_quarkus/tasks/start.yml +++ b/roles/keycloak_quarkus/tasks/start.yml @@ -14,3 +14,4 @@ until: keycloak_status.status == 200 retries: 25 delay: 10 + when: internal_force_health_check | default(keycloak_quarkus_restart_health_check) From f146eb5fda5f9444c1eb071701eed5a9f14d1ddc Mon Sep 17 00:00:00 2001 From: Ranabir Chakraborty Date: Fri, 11 Apr 2025 20:52:08 +0530 Subject: [PATCH 339/376] AMW-384 Keycloak realm variable keycloak_url with hard-coded http --- roles/keycloak/defaults/main.yml | 4 ++++ roles/keycloak/vars/main.yml | 3 --- roles/keycloak_realm/defaults/main.yml | 4 ++++ roles/keycloak_realm/vars/main.yml | 4 ---- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index cfa9a3f..137111f 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -118,3 +118,7 @@ keycloak_no_log: true ### logging configuration keycloak_log_target: /var/log/keycloak + +# locations +keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}" +keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}" diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 7f7dfd1..fe706db 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -1,9 +1,6 @@ --- # internal variables below -# locations -keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}" -keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}" keycloak: diff --git a/roles/keycloak_realm/defaults/main.yml b/roles/keycloak_realm/defaults/main.yml index b9e1e45..a294cbe 100644 --- a/roles/keycloak_realm/defaults/main.yml +++ b/roles/keycloak_realm/defaults/main.yml @@ -54,3 +54,7 @@ keycloak_client_users: [] ### List of Keycloak User Federation keycloak_user_federation: [] + +# other settings +keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + (keycloak_jboss_port_offset | default(0)) }}" +keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + (keycloak_jboss_port_offset | default(0)) }}" diff --git a/roles/keycloak_realm/vars/main.yml b/roles/keycloak_realm/vars/main.yml index 7664f8c..ad9bd8e 100644 --- a/roles/keycloak_realm/vars/main.yml +++ b/roles/keycloak_realm/vars/main.yml @@ -3,7 +3,3 @@ # name of the realm to create, this is a required variable keycloak_realm: - -# other settings -keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + (keycloak_jboss_port_offset | default(0)) }}" -keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + (keycloak_jboss_port_offset | default(0)) }}" From 671cf4eb537a49f1cf0f67e75517ba4808705e24 Mon Sep 17 00:00:00 2001 From: Preston Doster Date: Sun, 13 Apr 2025 10:17:22 -0500 Subject: [PATCH 340/376] Updating example playbooks to use `bootstrap` admin password It looks like the underlying `quarkus` provider has changed to use `keycloak_quarkus_bootstrap_admin_password`. --- playbooks/keycloak_quarkus.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index 84d1774..b8aedf2 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -2,7 +2,7 @@ - name: Playbook for Keycloak X Hosts with HTTPS enabled hosts: all vars: - keycloak_quarkus_admin_pass: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_hostname: http://localhost keycloak_quarkus_port: 8443 keycloak_quarkus_log: file From 7738e0feb1e70b6a6a68a38871c396d9e64dc097 Mon Sep 17 00:00:00 2001 From: Preston Doster Date: Sun, 13 Apr 2025 10:18:27 -0500 Subject: [PATCH 341/376] Update keycloak_quarkus_dev.yml --- playbooks/keycloak_quarkus_dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/keycloak_quarkus_dev.yml b/playbooks/keycloak_quarkus_dev.yml index 0c74c36..c8bb54e 100644 --- a/playbooks/keycloak_quarkus_dev.yml +++ b/playbooks/keycloak_quarkus_dev.yml @@ -2,7 +2,7 @@ - name: Playbook for Keycloak X Hosts in develop mode hosts: all vars: - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_hostname: http://localhost keycloak_quarkus_port: 8080 keycloak_quarkus_log: file From e9061b29efced4c721fee7926494f779808bcb5f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 16 Apr 2025 10:31:48 +0200 Subject: [PATCH 342/376] Rename parameters from jdbc to db --- molecule/quarkus_ha/converge.yml | 2 +- roles/keycloak_quarkus/README.md | 8 ++++---- roles/keycloak_quarkus/defaults/main.yml | 6 +++--- roles/keycloak_quarkus/meta/argument_specs.yml | 10 +++++----- roles/keycloak_quarkus/tasks/install.yml | 4 ++-- roles/keycloak_quarkus/tasks/jdbc_driver.yml | 4 ++-- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 4 ++-- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/molecule/quarkus_ha/converge.yml b/molecule/quarkus_ha/converge.yml index d37ad79..fa5314f 100644 --- a/molecule/quarkus_ha/converge.yml +++ b/molecule/quarkus_ha/converge.yml @@ -24,6 +24,6 @@ keycloak_quarkus_restart_strategy: restart/serial.yml keycloak_quarkus_db_user: keycloak keycloak_quarkus_db_pass: mysecretpass - keycloak_quarkus_jdbc_url: jdbc:postgresql://postgres:5432/keycloak + keycloak_quarkus_db_url: jdbc:postgresql://postgres:5432/keycloak roles: - role: keycloak_quarkus diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index fb30ce9..03a5a7a 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -130,14 +130,14 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_jdbc_engine` | Database engine [mariadb,postres,mssql] | `postgres` | +|`keycloak_quarkus_db_engine` | Database engine [mariadb,postres,mssql] | `postgres` | |`keycloak_quarkus_db_user` | User for database connection | `keycloak-user` | |`keycloak_quarkus_db_pass` | Password for database connection | `keycloak-pass` | -|`keycloak_quarkus_jdbc_url` | JDBC URL for connecting to database | `jdbc:postgresql://localhost:5432/keycloak` | -|`keycloak_quarkus_jdbc_driver_version` | Version for JDBC driver | `9.4.1212` | +|`keycloak_quarkus_db_url` | JDBC URL for connecting to database | `jdbc:postgresql://localhost:5432/keycloak` | +|`keycloak_quarkus_db_driver_version` | Version for JDBC engine driver | `9.4.1212` | -#### Remote caches configuration +#### Cache configuration | Variable | Description | Default | |:---------|:------------|:--------| diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 0512960..14f9fc9 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -120,12 +120,12 @@ keycloak_quarkus_ispn_trust_store_path: /etc/pki/java/cacerts keycloak_quarkus_ispn_trust_store_password: changeit ### database backend engine: values [ 'postgres', 'mariadb' ] -keycloak_quarkus_jdbc_engine: postgres +keycloak_quarkus_db_engine: postgres ### database backend credentials keycloak_quarkus_db_user: keycloak-user keycloak_quarkus_db_pass: keycloak-pass -keycloak_quarkus_jdbc_url: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].url }}" -keycloak_quarkus_jdbc_driver_version: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].version }}" +keycloak_quarkus_db_url: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].url }}" +keycloak_quarkus_db_driver_version: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].version }}" # override the variables above, following defaults show minimum supported versions keycloak_quarkus_default_jdbc: postgres: diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 4a3b7c4..c793e5f 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -287,7 +287,7 @@ argument_specs: default: "changeit" description: "Password for infinispan certificate keystore" type: "str" - keycloak_quarkus_jdbc_engine: + keycloak_quarkus_db_engine: default: "postgres" description: "Database engine [mariadb,postres,mssql]" type: "str" @@ -299,12 +299,12 @@ argument_specs: default: "keycloak-pass" description: "Password for database connection" type: "str" - keycloak_quarkus_jdbc_url: - default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].url }}" + keycloak_quarkus_db_url: + default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].url }}" description: "JDBC URL for connecting to database" type: "str" - keycloak_quarkus_jdbc_driver_version: - default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].version }}" + keycloak_quarkus_db_driver_version: + default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].version }}" description: "Version for JDBC driver" type: "str" keycloak_quarkus_log: diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index c602d8c..c664d05 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -202,11 +202,11 @@ - keycloak_quarkus_cert_file_copy_enabled is defined and keycloak_quarkus_cert_file_copy_enabled - keycloak_quarkus_cert_file_src | length > 0 -- name: "Install {{ keycloak_quarkus_jdbc_engine }} JDBC driver" +- name: "Install {{ keycloak_quarkus_db_engine }} JDBC driver" ansible.builtin.include_tasks: jdbc_driver.yml when: - rhbk_enable is defined and rhbk_enable - - keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url is defined + - keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].driver_jar_url is defined - name: "Download custom providers via http" ansible.builtin.get_url: diff --git a/roles/keycloak_quarkus/tasks/jdbc_driver.yml b/roles/keycloak_quarkus/tasks/jdbc_driver.yml index 880a915..ba3f4b8 100644 --- a/roles/keycloak_quarkus/tasks/jdbc_driver.yml +++ b/roles/keycloak_quarkus/tasks/jdbc_driver.yml @@ -7,9 +7,9 @@ (keycloak_quarkus_jdbc_download_user is undefined and keycloak_quarkus_jdbc_download_pass is not undefined) or (keycloak_quarkus_jdbc_download_pass is undefined and keycloak_quarkus_jdbc_download_user is not undefined) -- name: "Retrieve JDBC Driver from {{ keycloak_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" +- name: "Retrieve JDBC Driver from {{ keycloak_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].driver_jar_url) }}" ansible.builtin.get_url: - url: "{{ keycloak_quarkus_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" + url: "{{ keycloak_quarkus_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].driver_jar_url) }}" dest: "{{ keycloak.home }}/providers" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index f11e3ec..6a4a6c1 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -2,8 +2,8 @@ {% if keycloak_quarkus_db_enabled %} # Database -db={{ keycloak_quarkus_jdbc_engine }} -db-url={{ keycloak_quarkus_jdbc_url }} +db={{ keycloak_quarkus_db_engine }} +db-url={{ keycloak_quarkus_db_url }} db-username={{ keycloak_quarkus_db_user }} {% if not keycloak.config_key_store_enabled %} db-password={{ keycloak_quarkus_db_pass }} From c7ce7be6c4fc0cc99d3acf5600cdfc8c28d1637f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 16 Apr 2025 10:42:07 +0200 Subject: [PATCH 343/376] drop ajp port parameter --- roles/keycloak_quarkus/README.md | 1 - roles/keycloak_quarkus/defaults/main.yml | 1 - roles/keycloak_quarkus/meta/argument_specs.yml | 4 ---- 3 files changed, 6 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 03a5a7a..dc7ced7 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -53,7 +53,6 @@ Role Defaults |`keycloak_quarkus_http_port`| HTTP listening port | `8080` | |`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_http_management_port`| Port of the management interface. Relevant only when something is exposed on the management interface - see the guide for details. | `9000` | -|`keycloak_quarkus_ajp_port`| AJP port | `8009` | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` | |`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 14f9fc9..996d950 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -37,7 +37,6 @@ keycloak_quarkus_http_enabled: true keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 keycloak_quarkus_http_management_port: 9000 -keycloak_quarkus_ajp_port: 8009 keycloak_quarkus_jgroups_port: 7800 keycloak_quarkus_java_heap_opts: "-Xms1024m -Xmx2048m" keycloak_quarkus_java_jvm_opts: "-XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index c793e5f..d42bec3 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -191,10 +191,6 @@ argument_specs: default: 9000 description: "Port of the management interface. Relevant only when something is exposed on the management interface - see the guide for details." type: "int" - keycloak_quarkus_ajp_port: - default: 8009 - description: "AJP port" - type: "int" keycloak_quarkus_jgroups_port: default: 7800 description: "jgroups cluster tcp port" From 69a947c0b6961b35d541c141786c80d0d2ecfc9f Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 16 Apr 2025 11:34:12 +0200 Subject: [PATCH 344/376] rename _admin to _hostname_admin --- roles/keycloak_quarkus/README.md | 16 ++++++++++------ roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++-- roles/keycloak_quarkus/tasks/deprecations.yml | 6 +++--- .../keycloak_quarkus/templates/keycloak.conf.j2 | 2 +- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index dc7ced7..6427209 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -64,10 +64,8 @@ Role Defaults |`keycloak_quarkus_java_jvm_opts`| Other JVM settings | same as keycloak | |`keycloak_quarkus_java_opts`| JVM arguments; if overridden, it takes precedence over `keycloak_quarkus_java_*` | `{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}` | |`keycloak_quarkus_additional_env_vars` | List of additional env variables of { key: str, value: str} to be put in sysconfig file | `[]` | -|`keycloak_quarkus_hostname`| Address at which is the server exposed. Can be a full URL, or just a hostname. When only hostname is provided, scheme, port and context path are resolved from the request. | | |`keycloak_quarkus_frontend_url`| Deprecated, use `keycloak_quarkus_hostname` instead. | | -|`keycloak_quarkus_admin`| Set the base URL for accessing the administration console, including scheme, host, port and path | | -|`keycloak_quarkus_admin_url`| Deprecated, use `keycloak_quarkus_admin` instead. | | +|`keycloak_quarkus_admin_url`| Deprecated, use `keycloak_quarkus_hostname_admin` instead. | | |`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | |`keycloak_quarkus_http_management_relative_path` | Set the path relative to / for serving resources from management interface. The path must start with a /. If not given, the value is inherited from HTTP options. Relevant only when something is exposed on the management interface - see the guide for details. | `/` | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | @@ -119,12 +117,20 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_http_relative_path`| Set the path relative to / for serving resources. The path must start with a / | `/` | +|`keycloak_quarkus_hostname`| Address at which is the server exposed. Can be a full URL, or just a hostname. When only hostname is provided, scheme, port and context path are resolved from the request. | | +|`keycloak_quarkus_hostname_admin`| Set the base URL for accessing the administration console, including scheme, host, port and path | | |`keycloak_quarkus_hostname_strict`| Disables dynamically resolving the hostname from request headers | `true` | |`keycloak_quarkus_hostname_backchannel_dynamic`| Enables dynamic resolving of backchannel URLs, including hostname, scheme, port and context path. Set to true if your application accesses Keycloak via a private network. If set to true, hostname option needs to be specified as a full URL. | `false` | |`keycloak_quarkus_hostname_strict_backchannel`| Deprecated, use (the inverted!)`keycloak_quarkus_hostname_backchannel_dynamic` instead. | | +#### HTTP(S) configuration +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_http_relative_path`| Set the path relative to / for serving resources. The path must start with a / | `/` | + + + #### Database configuration | Variable | Description | Default | @@ -250,8 +256,6 @@ Role Variables |:---------|:------------|----------| |`keycloak_quarkus_bootstrap_admin_password`| Password of console admin account | `yes` | |`keycloak_quarkus_admin_pass`| Deprecated, use `keycloak_quarkus_bootstrap_admin_password` instead. | | -|`keycloak_quarkus_frontend_url`| Base URL for frontend URLs, including scheme, host, port and path | `no` | -|`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` | |`keycloak_quarkus_ks_vault_pass`| The password for accessing the keystore vault SPI | `no` | |`keycloak_quarkus_alternate_download_url`| Alternate location with optional authentication for downloading RHBK | `no` | |`keycloak_quarkus_download_user`| Optional username for http authentication | `no*` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 996d950..ed3dfab 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -79,7 +79,7 @@ keycloak_quarkus_systemd_wait_for_delay: 10 ### keycloak frontend url keycloak_quarkus_hostname: -keycloak_quarkus_admin: +keycloak_quarkus_hostname_admin: ### Set the path relative to / for serving resources. The path must start with a / ### (set to `/auth` for retrocompatibility with pre-quarkus releases) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index d42bec3..901e774 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -239,13 +239,13 @@ argument_specs: required: false description: "Deprecated in v26, use keycloak_quarkus_hostname instead." type: "str" - keycloak_quarkus_admin: + keycloak_quarkus_hostname_admin: required: false description: "Service URL for the admin console" type: "str" keycloak_quarkus_admin_url: required: false - description: "Deprecated in v26, use keycloak_quarkus_admin instead." + description: "Deprecated in v26, use keycloak_quarkus_hostname_admin instead." type: "str" keycloak_quarkus_metrics_enabled: default: false diff --git a/roles/keycloak_quarkus/tasks/deprecations.yml b/roles/keycloak_quarkus/tasks/deprecations.yml index fe269e9..3d1b9d7 100644 --- a/roles/keycloak_quarkus/tasks/deprecations.yml +++ b/roles/keycloak_quarkus/tasks/deprecations.yml @@ -86,16 +86,16 @@ - print deprecation warning # https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options -- name: Check deprecation of keycloak_quarkus_admin_url -> keycloak_quarkus_admin +- name: Check deprecation of keycloak_quarkus_admin_url -> keycloak_quarkus_hostname_admin when: - - keycloak_quarkus_admin is not defined + - keycloak_quarkus_hostname_admin is not defined - keycloak_quarkus_admin_url is defined - keycloak_quarkus_admin_url != '' delegate_to: localhost run_once: true changed_when: keycloak_quarkus_show_deprecation_warnings ansible.builtin.set_fact: - keycloak_quarkus_admin: "{{ keycloak_quarkus_admin_url }}" + keycloak_quarkus_hostname_admin: "{{ keycloak_quarkus_admin_url }}" deprecated_variable: "keycloak_quarkus_admin_url" # read in deprecation handler notify: - print deprecation warning diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 6a4a6c1..f15bbd8 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -50,7 +50,7 @@ https-trust-store-password={{ keycloak_quarkus_https_trust_store_password }} # Client URL configuration hostname={{ keycloak_quarkus_hostname }} -hostname-admin={{ keycloak_quarkus_admin }} +hostname-admin={{ keycloak_quarkus_hostname_admin }} hostname-strict={{ keycloak_quarkus_hostname_strict | lower }} hostname-backchannel-dynamic={{ keycloak_quarkus_hostname_backchannel_dynamic | lower }} From 70d61ce8dee578858f8803251b58ca8cafab520d Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 16 Apr 2025 11:58:04 +0200 Subject: [PATCH 345/376] rename ispn parameters --- roles/keycloak_quarkus/README.md | 79 ++++++++++--------- .../keycloak_quarkus/meta/argument_specs.yml | 18 ++--- 2 files changed, 46 insertions(+), 51 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 6427209..dac1dd2 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -50,9 +50,6 @@ Role Defaults |`keycloak_quarkus_host`| Deprecated, use `keycloak_quarkus_hostname` instead. | | |`keycloak_quarkus_port`| Deprecated, use `keycloak_quarkus_hostname` instead. | | |`keycloak_quarkus_path`| Deprecated, use `keycloak_quarkus_hostname` instead. | | -|`keycloak_quarkus_http_port`| HTTP listening port | `8080` | -|`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | -|`keycloak_quarkus_http_management_port`| Port of the management interface. Relevant only when something is exposed on the management interface - see the guide for details. | `9000` | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` | |`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` | @@ -66,26 +63,8 @@ Role Defaults |`keycloak_quarkus_additional_env_vars` | List of additional env variables of { key: str, value: str} to be put in sysconfig file | `[]` | |`keycloak_quarkus_frontend_url`| Deprecated, use `keycloak_quarkus_hostname` instead. | | |`keycloak_quarkus_admin_url`| Deprecated, use `keycloak_quarkus_hostname_admin` instead. | | -|`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | -|`keycloak_quarkus_http_management_relative_path` | Set the path relative to / for serving resources from management interface. The path must start with a /. If not given, the value is inherited from HTTP options. Relevant only when something is exposed on the management interface - see the guide for details. | `/` | -|`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | |`keycloak_quarkus_health_check_url`| Full URL (including scheme, host, path, fragment etc.) used for health check endpoint; keycloak_quarkus_hostname will NOT be prepended; helpful when health checks should happen against http port, but keycloak_quarkus_hostname uses https scheme per default | `` | |`keycloak_quarkus_health_check_url_path`| Path to the health check endpoint; keycloak_quarkus_hostname will be prepended automatically; Note that keycloak_quarkus_health_check_url takes precedence over this property | `realms/master/.well-known/openid-configuration` | -|`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` | -|`keycloak_quarkus_key_file_copy_enabled`| Enable copy of key file to target host | `False` | -|`keycloak_quarkus_key_content`| Content of the TLS private key. Use `"{{ lookup('file', 'server.key.pem') }}"` to lookup a file. | `""` | -|`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `/etc/pki/tls/private/server.key.pem` | -|`keycloak_quarkus_cert_file_copy_enabled`| Enable copy of cert file to target host | `False`| -|`keycloak_quarkus_cert_file_src`| Set the source file path | `""` | -|`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `/etc/pki/tls/certs/server.crt.pem` | -|`keycloak_quarkus_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` | -|`keycloak_quarkus_key_store_file`| Deprecated, use `keycloak_quarkus_https_key_store_file` instead. || -|`keycloak_quarkus_key_store_password`| Deprecated, use `keycloak_quarkus_https_key_store_password` instead.|| -|`keycloak_quarkus_https_key_store_file`| The file path to the key store | `{{ keycloak.home }}/conf/key_store.p12` | -|`keycloak_quarkus_https_key_store_password`| Password for the key store | `""` | -|`keycloak_quarkus_https_trust_store_enabled`| Enable configuration of the https trust store | `False` | -|`keycloak_quarkus_https_trust_store_file`| The file path to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` | -|`keycloak_quarkus_https_trust_store_password`| Password for the trust store | `""` | |`keycloak_quarkus_proxy_headers`| Parse reverse proxy headers (`forwarded` or `xforwarded`) | `""` | |`keycloak_quarkus_config_key_store_file`| Path to the configuration key store; only used if `keycloak_quarkus_keystore_password` is not empty | `{{ keycloak.home }}/conf/conf_store.p12` if `keycloak_quarkus_keystore_password != ''`, else `''` | |`keycloak_quarkus_config_key_store_password`| Password of the configuration keystore; if non-empty, `keycloak_quarkus_db_pass` will be saved to the keystore at `keycloak_quarkus_config_key_store_file` instead of being written to the configuration file in clear text | `""` | @@ -128,7 +107,27 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| |`keycloak_quarkus_http_relative_path`| Set the path relative to / for serving resources. The path must start with a / | `/` | - +|`keycloak_quarkus_http_port`| HTTP listening port | `8080` | +|`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | +|`keycloak_quarkus_http_management_port`| Port of the management interface. Relevant only when something is exposed on the management interface - see the guide for details. | `9000` | +|`keycloak_quarkus_https_key_store_file`| The file path to the key store | `{{ keycloak.home }}/conf/key_store.p12` | +|`keycloak_quarkus_https_key_store_password`| Password for the key store | `""` | +|`keycloak_quarkus_https_trust_store_enabled`| Enable configuration of the https trust store | `False` | +|`keycloak_quarkus_https_trust_store_file`| The file path to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` | +|`keycloak_quarkus_https_trust_store_password`| Password for the trust store | `""` | +|`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` | +|`keycloak_quarkus_key_file_copy_enabled`| Enable copy of key file to target host | `False` | +|`keycloak_quarkus_key_content`| Content of the TLS private key. Use `"{{ lookup('file', 'server.key.pem') }}"` to lookup a file. | `""` | +|`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `/etc/pki/tls/private/server.key.pem` | +|`keycloak_quarkus_cert_file_copy_enabled`| Enable copy of cert file to target host | `False`| +|`keycloak_quarkus_cert_file_src`| Set the source file path | `""` | +|`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `/etc/pki/tls/certs/server.crt.pem` | +|`keycloak_quarkus_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` | +|`keycloak_quarkus_key_store_file`| Deprecated, use `keycloak_quarkus_https_key_store_file` instead. || +|`keycloak_quarkus_key_store_password`| Deprecated, use `keycloak_quarkus_https_key_store_password` instead.|| +|`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | +|`keycloak_quarkus_http_management_relative_path` | Set the path relative to / for serving resources from management interface. The path must start with a /. If not given, the value is inherited from HTTP options. Relevant only when something is exposed on the management interface - see the guide for details. | `/` | +|`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | #### Database configuration @@ -146,13 +145,25 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_ispn_user` | Username for connecting to infinispan | `supervisor` | -|`keycloak_quarkus_ispn_pass` | Password for connecting to infinispan | `supervisor` | -|`keycloak_quarkus_ispn_hosts` | host name/port for connecting to infinispan, eg. host1:11222;host2:11222 | `localhost:11222` | -|`keycloak_quarkus_ispn_sasl_mechanism` | Infinispan auth mechanism | `SCRAM-SHA-512` | -|`keycloak_quarkus_ispn_use_ssl` | Whether infinispan uses TLS connection | `false` | -|`keycloak_quarkus_ispn_trust_store_path` | Path to infinispan server trust certificate | `/etc/pki/java/cacerts` | -|`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` | +|`keycloak_quarkus_cache_remote_username` | Username for connecting to infinispan | `supervisor` | +|`keycloak_quarkus_cache_remote_password` | Password for connecting to infinispan | `supervisor` | +|`keycloak_quarkus_cache_remote_host` | host name/port for connecting to infinispan, eg. host1:11222;host2:11222 | `localhost:11222` | +|`keycloak_quarkus_cache_remote_sasl_mechanism` | Infinispan auth mechanism | `SCRAM-SHA-512` | +|`keycloak_quarkus_cache_remote_tls_enabled` | Whether infinispan uses TLS connection | `false` | + + +#### Logging configuration + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_log`| Enable one or more log handlers in a comma-separated list | `file` | +|`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` | +|`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | +|`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | +|`keycloak_quarkus_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | +|`keycloak_quarkus_log_max_file_size`| Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): `[0-9]+[KkMmGgTtPpEeZzYy]?`. If no suffix is given, assume bytes. | `10M` | +|`keycloak_quarkus_log_max_backup_index`| Set the maximum number of archived log files to keep" | `10` | +|`keycloak_quarkus_log_file_suffix`| Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with `.zip` or `.gz`, the rotation file will also be compressed. | `.yyyy-MM-dd.zip` | #### Miscellaneous configuration @@ -168,14 +179,6 @@ Role Defaults |`keycloak_quarkus_master_realm` | Name for rest authentication realm | `master` | |`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` | |`keycloak_force_install` | Remove pre-existing versions of service | `False` | -|`keycloak_quarkus_log`| Enable one or more log handlers in a comma-separated list | `file` | -|`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` | -|`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | -|`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` | -|`keycloak_quarkus_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` | -|`keycloak_quarkus_log_max_file_size`| Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): `[0-9]+[KkMmGgTtPpEeZzYy]?`. If no suffix is given, assume bytes. | `10M` | -|`keycloak_quarkus_log_max_backup_index`| Set the maximum number of archived log files to keep" | `10` | -|`keycloak_quarkus_log_file_suffix`| Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with `.zip` or `.gz`, the rotation file will also be compressed. | `.yyyy-MM-dd.zip` | |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | @@ -183,7 +186,7 @@ Role Defaults |`keycloak_quarkus_show_deprecation_warnings`| Whether deprecation warnings should be shown | `True` | -#### Vault SPI +#### Vault configuration | Variable | Description | Default | |:---------|:------------|:--------| diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 901e774..1c995db 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -255,34 +255,26 @@ argument_specs: default: true description: "If the server should expose health check endpoints on the management interface" type: "bool" - keycloak_quarkus_ispn_user: + keycloak_quarkus_cache_remote_username: default: "supervisor" description: "Username for connecting to infinispan" type: "str" - keycloak_quarkus_ispn_pass: + keycloak_quarkus_cache_remote_password: default: "supervisor" description: "Password for connecting to infinispan" type: "str" - keycloak_quarkus_ispn_hosts: + keycloak_quarkus_cache_remote_host: default: "localhost:11222" description: "host name/port for connecting to infinispan, eg. host1:11222;host2:11222" type: "str" - keycloak_quarkus_ispn_sasl_mechanism: + keycloak_quarkus_cache_remote_sasl_mechanism: default: "SCRAM-SHA-512" description: "Infinispan auth mechanism" type: "str" - keycloak_quarkus_ispn_use_ssl: + keycloak_quarkus_cache_remote_tls_enabled: default: false description: "Whether infinispan uses TLS connection" type: "bool" - keycloak_quarkus_ispn_trust_store_path: - default: "/etc/pki/java/cacerts" - description: "Path to infinispan server trust certificate" - type: "str" - keycloak_quarkus_ispn_trust_store_password: - default: "changeit" - description: "Password for infinispan certificate keystore" - type: "str" keycloak_quarkus_db_engine: default: "postgres" description: "Database engine [mariadb,postres,mssql]" From b8028d376aa5e5063ec6f49a9bb1e9adb28925b9 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 16 Apr 2025 14:16:07 +0200 Subject: [PATCH 346/376] Rename and honor parameter keycloak_quarkus_http_host --- roles/keycloak_quarkus/README.md | 3 ++- roles/keycloak_quarkus/defaults/main.yml | 3 ++- roles/keycloak_quarkus/meta/argument_specs.yml | 6 +++++- roles/keycloak_quarkus/tasks/deprecations.yml | 13 +++++++++++++ roles/keycloak_quarkus/templates/cache-ispn.xml.j2 | 2 +- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 1 + 6 files changed, 24 insertions(+), 4 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index dac1dd2..7f93a9f 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -46,7 +46,7 @@ Role Defaults |:---------|:------------|:--------| |`keycloak_quarkus_bootstrap_admin_user`| Administration console user account | `admin` | |`keycloak_quarkus_admin_user`| Deprecated, use `keycloak_quarkus_bootstrap_admin_user` instead. | | -|`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | +|`keycloak_quarkus_bind_address`| Deprecated, use `keycloak_quarkus_http_host` instead | `0.0.0.0` | |`keycloak_quarkus_host`| Deprecated, use `keycloak_quarkus_hostname` instead. | | |`keycloak_quarkus_port`| Deprecated, use `keycloak_quarkus_hostname` instead. | | |`keycloak_quarkus_path`| Deprecated, use `keycloak_quarkus_hostname` instead. | | @@ -107,6 +107,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| |`keycloak_quarkus_http_relative_path`| Set the path relative to / for serving resources. The path must start with a / | `/` | +|`keycloak_quarkus_http_host`| The http host, ie. the address used to bind the service | `0.0.0.0` | |`keycloak_quarkus_http_port`| HTTP listening port | `8080` | |`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_http_management_port`| Port of the management interface. Relevant only when something is exposed on the management interface - see the guide for details. | `9000` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index ed3dfab..7fefc5a 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -32,7 +32,8 @@ keycloak_quarkus_bootstrap_admin_password: keycloak_quarkus_master_realm: master ### Configuration settings -keycloak_quarkus_bind_address: 0.0.0.0 +keycloak_quarkus_bind_address: 0.0.0.0 # deprecated use keycloak_quarkus_http_host +keycloak_quarkus_http_host: 0.0.0.0 keycloak_quarkus_http_enabled: true keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 1c995db..51b0d1f 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -82,7 +82,7 @@ argument_specs: type: "str" keycloak_quarkus_bind_address: default: "0.0.0.0" - description: "Address for binding service ports" + description: "Deprecated, use `keycloak_quarkus_http_host`" type: "str" keycloak_quarkus_hostname: description: >- @@ -102,6 +102,10 @@ argument_specs: default: true description: "Enable listener on HTTP port" type: "bool" + keycloak_quarkus_http_host: + default: '0.0.0.0' + description: "HTTP host, address for binding service ports" + type: "str" keycloak_quarkus_http_port: default: 8080 description: "HTTP port" diff --git a/roles/keycloak_quarkus/tasks/deprecations.yml b/roles/keycloak_quarkus/tasks/deprecations.yml index 3d1b9d7..0d370d5 100644 --- a/roles/keycloak_quarkus/tasks/deprecations.yml +++ b/roles/keycloak_quarkus/tasks/deprecations.yml @@ -145,5 +145,18 @@ notify: - print deprecation warning +- name: Check deprecation of keycloak_quarkus_bind_address -> keycloak_quarkus_http_host + when: + - keycloak_quarkus_bind_address is defined + - keycloak_quarkus_bind_address != '0.0.0.0' + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_http_host: "{{ keycloak_quarkus_bind_address }}" + deprecated_variable: "keycloak_quarkus_bind_address" # read in deprecation handler + notify: + - print deprecation warning + - name: Flush handlers ansible.builtin.meta: flush_handlers diff --git a/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 index 8ead247..e546ab8 100644 --- a/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 +++ b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 @@ -26,7 +26,7 @@ {% set stack_expression='stack="tcpping"' %} - + Date: Fri, 18 Apr 2025 17:59:16 +0200 Subject: [PATCH 347/376] Load envvars in kc rebuild --- molecule/quarkus/converge.yml | 3 +++ roles/keycloak_quarkus/tasks/rebuild_config.yml | 5 +---- roles/keycloak_quarkus/tasks/systemd.yml | 1 + roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index b7c15e1..cb3b9f8 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -23,6 +23,9 @@ keycloak_quarkus_systemd_wait_for_delay: 2 keycloak_quarkus_systemd_wait_for_log: true keycloak_quarkus_restart_health_check: false # would fail because of self-signed cert + keycloak_quarkus_additional_env_vars: + - key: KC_FEATURES_DISABLED + value: impersonation,kerberos keycloak_quarkus_providers: - id: http-client spi: connections diff --git a/roles/keycloak_quarkus/tasks/rebuild_config.yml b/roles/keycloak_quarkus/tasks/rebuild_config.yml index ac78504..1d43127 100644 --- a/roles/keycloak_quarkus/tasks/rebuild_config.yml +++ b/roles/keycloak_quarkus/tasks/rebuild_config.yml @@ -2,9 +2,6 @@ # cf. https://www.keycloak.org/server/configuration#_optimize_the_keycloak_startup - name: "Rebuild {{ keycloak.service_name }} config" ansible.builtin.shell: | # noqa blocked_modules shell is necessary here - {{ keycloak.home }}/bin/kc.sh build - environment: - PATH: "{{ keycloak_quarkus_java_home | default(keycloak_quarkus_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - JAVA_HOME: "{{ keycloak_quarkus_java_home | default(keycloak_quarkus_pkg_java_home, true) }}" + env -i bash -c "set -a ; source {{ keycloak_quarkus_sysconf_file }} ; {{ keycloak.home }}/bin/kc.sh build " become: true changed_when: true diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index 47f0570..e22b9fe 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -22,4 +22,5 @@ become: true register: systemdunit notify: + - rebuild keycloak config - restart keycloak diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index 244d9aa..c1b1c7b 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -7,7 +7,7 @@ KC_BOOTSTRAP_ADMIN_PASSWORD='{{ keycloak_quarkus_bootstrap_admin_password }}' {% endif %} PATH={{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }} -JAVA_OPTS={{ keycloak_quarkus_java_opts }} +JAVA_OPTS='{{ keycloak_quarkus_java_opts }}' # Custom ENV variables {% for env in keycloak_quarkus_additional_env_vars %} From f750e93d02c3dfc18ba373bd783bbacc5b678b23 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 22 Apr 2025 14:51:15 +0200 Subject: [PATCH 348/376] Add bash to preinstalled packages --- roles/keycloak_quarkus/vars/debian.yml | 1 + roles/keycloak_quarkus/vars/redhat.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/roles/keycloak_quarkus/vars/debian.yml b/roles/keycloak_quarkus/vars/debian.yml index 29f190a..0af3443 100644 --- a/roles/keycloak_quarkus/vars/debian.yml +++ b/roles/keycloak_quarkus/vars/debian.yml @@ -2,6 +2,7 @@ keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('openjdk-17-jdk-headless') }}" keycloak_quarkus_prereq_package_list: - "{{ keycloak_quarkus_varjvm_package }}" + - bash - unzip - procps - apt diff --git a/roles/keycloak_quarkus/vars/redhat.yml b/roles/keycloak_quarkus/vars/redhat.yml index 9af167f..458c841 100644 --- a/roles/keycloak_quarkus/vars/redhat.yml +++ b/roles/keycloak_quarkus/vars/redhat.yml @@ -2,6 +2,7 @@ keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('java-21-openjdk-headless') }}" keycloak_quarkus_prereq_package_list: - "{{ keycloak_quarkus_varjvm_package }}" + - bash - unzip - procps-ng - initscripts From c86dff66ba9617ac2c528e1eca4442d3878c677c Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 22 Apr 2025 20:18:48 +0200 Subject: [PATCH 349/376] double quote sysconfig envvars --- roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index c1b1c7b..9efd068 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -5,9 +5,9 @@ KC_BOOTSTRAP_ADMIN_PASSWORD='{{ keycloak_quarkus_bootstrap_admin_password }}' {% else %} {{ keycloak.bootstrap_mnemonic }} {% endif %} -PATH={{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }} -JAVA_OPTS='{{ keycloak_quarkus_java_opts }}' +PATH="{{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +JAVA_HOME="{{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }}" +JAVA_OPTS="{{ keycloak_quarkus_java_opts }}" # Custom ENV variables {% for env in keycloak_quarkus_additional_env_vars %} From 2abc580041af016b0bf17a0d9c0046380b53d092 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 23 Apr 2025 11:47:38 +0000 Subject: [PATCH 350/376] Update changelog for release 3.0.0 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 29 ++++++++++++++++++++++++ changelogs/changelog.yaml | 47 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 37a3923..d6b2d25 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,35 @@ middleware\_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v3.0.0 +====== + +Minor Changes +------------- + +- Add theme cache invalidation handler `#252 `_ +- keycloak_realm: change url variables to defaults `#268 `_ + +Breaking Changes / Porting Guide +-------------------------------- + +- Bump major and ansible-core versions `#266 `_ +- Rename parameters to follow upstream `#270 `_ +- Update for keycloak v26 `#254 `_ + +Bugfixes +-------- + +- Access token lifespan is too short for ansible run `#251 `_ +- Load environment vars during kc rebuild `#274 `_ +- Rebuild config and restart service for local providers `#250 `_ +- Rename and honour parameter ``keycloak_quarkus_http_host`` `#271 `_ + +New Modules +----------- + +- middleware_automation.keycloak.keycloak_realm - Allows administration of Keycloak realm via Keycloak API + v2.4.3 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 40a7db3..3d25cd2 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -613,3 +613,50 @@ releases: fragments: - 241.yaml release_date: '2024-10-16' + 3.0.0: + changes: + breaking_changes: + - 'Bump major and ansible-core versions `#266 `_ + + ' + - 'Rename parameters to follow upstream `#270 `_ + + ' + - 'Update for keycloak v26 `#254 `_ + + ' + bugfixes: + - 'Access token lifespan is too short for ansible run `#251 `_ + + ' + - 'Load environment vars during kc rebuild `#274 `_ + + ' + - 'Rebuild config and restart service for local providers `#250 `_ + + ' + - 'Rename and honour parameter ``keycloak_quarkus_http_host`` `#271 `_ + + ' + minor_changes: + - 'Add theme cache invalidation handler `#252 `_ + + ' + - 'keycloak_realm: change url variables to defaults `#268 `_ + + ' + fragments: + - 250.yaml + - 251.yaml + - 252.yaml + - 254.yaml + - 266.yaml + - 268.yaml + - 270.yaml + - 271.yaml + - 274.yaml + modules: + - description: Allows administration of Keycloak realm via Keycloak API + name: keycloak_realm + namespace: '' + release_date: '2025-04-23' From d97044523d3a4133c0a70523aeb5ca90ebc16940 Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Wed, 23 Apr 2025 11:47:54 +0000 Subject: [PATCH 351/376] Bump version to 3.0.1 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 76c46c4..0b53eba 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "3.0.0" +version: "3.0.1" readme: README.md authors: - Romain Pelisse From 5beb5dcda4b8440503c2e0b55ea21e536bd07c78 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 2 May 2025 10:50:01 +0200 Subject: [PATCH 352/376] Add trigger on envvars file change --- roles/keycloak_quarkus/tasks/systemd.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/keycloak_quarkus/tasks/systemd.yml b/roles/keycloak_quarkus/tasks/systemd.yml index e22b9fe..fda37f5 100644 --- a/roles/keycloak_quarkus/tasks/systemd.yml +++ b/roles/keycloak_quarkus/tasks/systemd.yml @@ -10,6 +10,7 @@ vars: keycloak_sys_pkg_java_home: "{{ keycloak_quarkus_pkg_java_home }}" notify: + - rebuild keycloak config - restart keycloak - name: "Configure systemd unit file for keycloak service" From b8a2ebc699fc89577c446848cd34ad4ffc1d1b94 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 2 May 2025 10:55:17 +0200 Subject: [PATCH 353/376] update keycloak version --- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 7fefc5a..1e83749 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 26.0.7 +keycloak_quarkus_version: 26.0.8 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 51b0d1f..6b0b8c2 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -2,7 +2,7 @@ argument_specs: main: options: keycloak_quarkus_version: - default: "26.0.7" + default: "26.0.8" description: "keycloak.org package version" type: "str" keycloak_quarkus_archive: @@ -471,7 +471,7 @@ argument_specs: downstream: options: rhbk_version: - default: "26.0.7" + default: "26.0.11" description: "Red Hat Build of Keycloak version" type: "str" rhbk_archive: From 9974ab2ee1452d1af7c67966406c3588bf09306b Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 2 May 2025 11:18:57 +0200 Subject: [PATCH 354/376] update molecule scenario --- molecule/quarkus_upgrade/converge.yml | 3 +++ molecule/quarkus_upgrade/prepare.yml | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/molecule/quarkus_upgrade/converge.yml b/molecule/quarkus_upgrade/converge.yml index 9b57436..0f67169 100644 --- a/molecule/quarkus_upgrade/converge.yml +++ b/molecule/quarkus_upgrade/converge.yml @@ -5,6 +5,9 @@ - vars.yml vars: keycloak_quarkus_show_deprecation_warnings: false + keycloak_quarkus_additional_env_vars: + - key: KC_FEATURES_DISABLED + value: ciba,device-flow,impersonation,kerberos,docker keycloak_quarkus_version: 26.0.7 roles: - role: keycloak_quarkus diff --git a/molecule/quarkus_upgrade/prepare.yml b/molecule/quarkus_upgrade/prepare.yml index a6892e3..1be16d6 100644 --- a/molecule/quarkus_upgrade/prepare.yml +++ b/molecule/quarkus_upgrade/prepare.yml @@ -5,7 +5,10 @@ - vars.yml vars: sudo_pkg_name: sudo - keycloak_quarkus_version: 24.0.5 + keycloak_quarkus_version: 26.0.4 + keycloak_quarkus_additional_env_vars: + - key: KC_FEATURES_DISABLED + value: impersonation,kerberos pre_tasks: - name: Install sudo ansible.builtin.apt: @@ -44,6 +47,7 @@ changed_when: false roles: - role: keycloak_quarkus + post_tasks: - name: "Delete custom fact" ansible.builtin.file: From c45f7c0d60b3cd8a02875174d4e60572017aaed8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 2 May 2025 11:26:27 +0200 Subject: [PATCH 355/376] Update remote cache default --- molecule/default/prepare.yml | 6 +----- roles/keycloak_quarkus/defaults/main.yml | 14 ++++++------- .../templates/quarkus.properties.j2 | 20 +++++++++---------- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index eefd5cf..77a7723 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -7,10 +7,6 @@ tasks: - name: "Run preparation common to all scenario" ansible.builtin.include_tasks: ../prepare.yml - vars: - assets: - - "{{ assets_server }}/sso/7.6.0/rh-sso-7.6.0-server-dist.zip" - - "{{ assets_server }}/sso/7.6.1/rh-sso-7.6.1-patch.zip" - name: Create controller directory for downloads ansible.builtin.file: # noqa risky-file-permissions delegated, uses controller host user @@ -22,7 +18,7 @@ - name: Download keycloak archive to controller directory ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user - url: https://github.com/keycloak/keycloak/releases/download/26.0.7/keycloak-26.0.7.zip + url: https://github.com/keycloak/keycloak/releases/download/26.0.8/keycloak-26.0.8.zip dest: /tmp/keycloak mode: '0640' delegate_to: localhost diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 1e83749..66fc8e1 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -110,14 +110,12 @@ keycloak_quarkus_metrics_enabled: false keycloak_quarkus_health_enabled: true ### infinispan remote caches access (hotrod) -keycloak_quarkus_ispn_user: supervisor -keycloak_quarkus_ispn_pass: supervisor -keycloak_quarkus_ispn_hosts: "localhost:11222" -keycloak_quarkus_ispn_sasl_mechanism: SCRAM-SHA-512 -keycloak_quarkus_ispn_use_ssl: false -# if ssl is enabled, import ispn server certificate here -keycloak_quarkus_ispn_trust_store_path: /etc/pki/java/cacerts -keycloak_quarkus_ispn_trust_store_password: changeit +keycloak_quarkus_cache_remote_username: supervisor +keycloak_quarkus_cache_remote_password: supervisor +keycloak_quarkus_cache_remote_host: "localhost:11222" +keycloak_quarkus_cache_remote_tls_enabled: false +keycloak_quarkus_cache_remote_sasl_mechanism: SCRAM-SHA-512 + ### database backend engine: values [ 'postgres', 'mariadb' ] keycloak_quarkus_db_engine: postgres diff --git a/roles/keycloak_quarkus/templates/quarkus.properties.j2 b/roles/keycloak_quarkus/templates/quarkus.properties.j2 index 93152e8..06d9077 100644 --- a/roles/keycloak_quarkus/templates/quarkus.properties.j2 +++ b/roles/keycloak_quarkus/templates/quarkus.properties.j2 @@ -1,22 +1,22 @@ {{ ansible_managed | comment }} {% if keycloak_quarkus_ha_enabled %} {% if keycloak_quarkus_version.split('.')[0] | int < 22 %} -quarkus.infinispan-client.server-list={{ keycloak_quarkus_ispn_hosts }} -quarkus.infinispan-client.auth-username={{ keycloak_quarkus_ispn_user }} -quarkus.infinispan-client.auth-password={{ keycloak_quarkus_ispn_pass }} +quarkus.infinispan-client.server-list={{ keycloak_quarkus_cache_remote_host }} +quarkus.infinispan-client.auth-username={{ keycloak_quarkus_cache_remote_username }} +quarkus.infinispan-client.auth-password={{ keycloak_quarkus_cache_remote_password }} {% else %} -quarkus.infinispan-client.hosts={{ keycloak_quarkus_ispn_hosts }} -quarkus.infinispan-client.username={{ keycloak_quarkus_ispn_user }} -quarkus.infinispan-client.password={{ keycloak_quarkus_ispn_pass }} +quarkus.infinispan-client.hosts={{ keycloak_quarkus_cache_remote_host }} +quarkus.infinispan-client.username={{ keycloak_quarkus_cache_remote_username }} +quarkus.infinispan-client.password={{ keycloak_quarkus_cache_remote_password }} {% endif %} quarkus.infinispan-client.client-intelligence=HASH_DISTRIBUTION_AWARE quarkus.infinispan-client.use-auth=true quarkus.infinispan-client.auth-realm=default quarkus.infinispan-client.auth-server-name=infinispan -quarkus.infinispan-client.sasl-mechanism={{ keycloak_quarkus_ispn_sasl_mechanism }} -{% if keycloak_quarkus_ispn_use_ssl %} -quarkus.infinispan-client.trust-store={{ keycloak_quarkus_ispn_trust_store_path }} -quarkus.infinispan-client.trust-store-password={{ keycloak_quarkus_ispn_trust_store_password }} +quarkus.infinispan-client.sasl-mechanism={{ keycloak_quarkus_cache_remote_sasl_mechanism }} +{% if keycloak_quarkus_cache_remote_tls_enabled %} +quarkus.infinispan-client.trust-store={{ keycloak_quarkus_https_trust_store_file }} +quarkus.infinispan-client.trust-store-password={{ keycloak_quarkus_https_trust_store_password }} quarkus.infinispan-client.trust-store-type=jks {% endif %} #quarkus.infinispan-client.use-schema-registration=true From 88be78926073dbaebb769eb8b02f321c024e653f Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Fri, 2 May 2025 09:48:54 +0000 Subject: [PATCH 356/376] Update changelog for release 3.0.1 Signed-off-by: ansible-middleware-core --- CHANGELOG.rst | 13 +++++++++++++ changelogs/changelog.yaml | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d6b2d25..b290328 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,19 @@ middleware\_automation.keycloak Release Notes This changelog describes changes after version 0.2.6. +v3.0.1 +====== + +Minor Changes +------------- + +- Version update to 26.0.8 / rhbk 26.0.11 `#277 `_ + +Bugfixes +-------- + +- Trigger rebuild handler on envvars file change `#276 `_ + v3.0.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 3d25cd2..9b09e13 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -660,3 +660,17 @@ releases: name: keycloak_realm namespace: '' release_date: '2025-04-23' + 3.0.1: + changes: + bugfixes: + - 'Trigger rebuild handler on envvars file change `#276 `_ + + ' + minor_changes: + - 'Version update to 26.0.8 / rhbk 26.0.11 `#277 `_ + + ' + fragments: + - 276.yaml + - 277.yaml + release_date: '2025-05-02' From e0c4b1e1ff14c8ba09487dd9c64448a3e91803bd Mon Sep 17 00:00:00 2001 From: ansible-middleware-core Date: Fri, 2 May 2025 09:49:08 +0000 Subject: [PATCH 357/376] Bump version to 3.0.2 --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 0b53eba..006207e 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "3.0.1" +version: "3.0.2" readme: README.md authors: - Romain Pelisse From 5cd400b053d8a2a973fa5703f41df7f7dcbffdb0 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 6 May 2025 15:16:50 +0200 Subject: [PATCH 358/376] feat: introduce `checksum` for keycloak_quarkus_providers (#279) --- molecule/quarkus/converge.yml | 3 +++ roles/keycloak_quarkus/README.md | 4 ++++ roles/keycloak_quarkus/tasks/install.yml | 2 ++ 3 files changed, 9 insertions(+) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index cb3b9f8..a836d1a 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -36,6 +36,9 @@ value: 10 - id: spid-saml url: https://github.com/italia/spid-keycloak-provider/releases/download/24.0.2/spid-provider.jar + - id: spid-saml-w-checksum + url: https://github.com/italia/spid-keycloak-provider/releases/download/24.0.2/spid-provider.jar + checksum: sha256:fbb50e73739d7a6d35b5bff611b1c01668b29adf6f6259624b95e466a305f377 - id: keycloak-kerberos-federation maven: repository_url: https://repo1.maven.org/maven2/ # https://mvnrepository.com/artifact/org.keycloak/keycloak-kerberos-federation/24.0.4 diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 7f93a9f..b5e7686 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -228,6 +228,10 @@ keycloak_quarkus_providers: properties: # optional, list of key-values - key: default-connection-pool-size value: 10 + checksum: sha256:D98291AC[...]B6DC7B97 # optional, checksum used to verify integrity: + # for `url` SPIs, use format: :, cf. ; + # for `local_path` SPIs, use SHA1 format + # for `maven` SPIs, this field is ignored since maven has integrity verification methods enabled by default ``` the definition above will generate the following build command: diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index c664d05..4719b64 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -215,6 +215,7 @@ owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: '0640' + checksum: "{{ item.checksum | default(omit) }}" become: true loop: "{{ keycloak_quarkus_providers }}" when: item.url is defined and item.url | length > 0 @@ -244,6 +245,7 @@ owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" mode: '0640' + checksum: "{{ item.checksum | default(omit) }}" become: true loop: "{{ keycloak_quarkus_providers }}" when: item.maven is defined From 0936d415c7fd460570d8304cb263be8382efd31a Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Fri, 9 May 2025 15:20:57 +0200 Subject: [PATCH 359/376] ci: update test linking removed url --- molecule/quarkus/converge.yml | 9 +++++---- roles/keycloak_quarkus/README.md | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index a836d1a..65da7bd 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -23,6 +23,7 @@ keycloak_quarkus_systemd_wait_for_delay: 2 keycloak_quarkus_systemd_wait_for_log: true keycloak_quarkus_restart_health_check: false # would fail because of self-signed cert + keycloak_quarkus_version: 26.2.0 keycloak_quarkus_additional_env_vars: - key: KC_FEATURES_DISABLED value: impersonation,kerberos @@ -50,10 +51,10 @@ # - id: my-static-theme # local_path: /tmp/my-static-theme.jar keycloak_quarkus_policies: - - name: "xato-net-10-million-passwords.txt" - url: "https://github.com/danielmiessler/SecLists/raw/master/Passwords/xato-net-10-million-passwords.txt" - - name: "xato-net-10-million-passwords-10.txt" - url: "https://github.com/danielmiessler/SecLists/raw/master/Passwords/xato-net-10-million-passwords-10.txt" + - name: "cain-and-abel.txt" + url: "https://github.com/danielmiessler/SecLists/raw/master/Passwords/Software/cain-and-abel.txt" + - name: "john-the-ripper.txt" + url: "https://github.com/danielmiessler/SecLists/raw/master/Passwords/Software/john-the-ripper.txt" type: password-blacklists roles: - role: keycloak_quarkus diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index b5e7686..2d87c2b 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -251,9 +251,9 @@ Provider definition: ```yaml keycloak_quarkus_policies: - - name: xato-net-10-million-passwords.txt # required, resulting file name - url: https://github.com/danielmiessler/SecLists/raw/master/Passwords/xato-net-10-million-passwords.txt # required, url for download - type: password-blacklists # optional, defaults to `password-blacklists`; supported values: [`password-blacklists`] + - name: john-the-ripper.txt # required, resulting file name + url: https://github.com/danielmiessler/SecLists/raw/master/Passwords/Software/john-the-ripper.txt # required, url for download + type: password-blacklists # optional, defaults to `password-blacklists`; supported values: [`password-blacklists`] ``` From c614af127e8270f68ec341e646d6e611df120054 Mon Sep 17 00:00:00 2001 From: Jonathan Wright Date: Tue, 13 May 2025 09:15:38 -0500 Subject: [PATCH 360/376] Add var to set the jgroups IP per host This is useful if the default route does not represent the network you want/need to use for cluster communication. --- molecule/debian/prepare.yml | 5 +++++ roles/keycloak_quarkus/README.md | 1 + roles/keycloak_quarkus/defaults/main.yml | 1 + roles/keycloak_quarkus/meta/argument_specs.yml | 4 ++++ roles/keycloak_quarkus/tasks/main.yml | 4 ++-- 5 files changed, 13 insertions(+), 2 deletions(-) diff --git a/molecule/debian/prepare.yml b/molecule/debian/prepare.yml index 267386e..ed21958 100644 --- a/molecule/debian/prepare.yml +++ b/molecule/debian/prepare.yml @@ -10,3 +10,8 @@ # - openjdk-21-jdk-headless # this is not available in ghcr.io/hspaans/molecule-containers:debian-11 (neither in debian-12) since the images are using outdated package sources - openjdk-17-jdk-headless state: present + - name: "Install iproute2" + ansible.builtin.apt: + name: + - iproute2 + state: present diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 2d87c2b..7aedb45 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -79,6 +79,7 @@ Role Defaults |`keycloak_quarkus_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` | |`keycloak_quarkus_ha_discovery`| Discovery protocol for HA cluster members | `TCPPING` | |`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` | +|`keycloak_quarkus_jgroups_ip`| Host jgroups IP. If changing this variable you must make sure it is always set for all hosts in your cluster. | `{{ ansible_default_ipv4.address }}` | |`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7800` | |`keycloak_quarkus_systemd_wait_for_port` | Whether systemd unit should wait for keycloak port before returning | `{{ keycloak_quarkus_ha_enabled }}` | |`keycloak_quarkus_systemd_wait_for_port_number`| Which port the systemd unit should wait for | `{{ keycloak_quarkus_https_port }}` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 66fc8e1..b4d5a37 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -38,6 +38,7 @@ keycloak_quarkus_http_enabled: true keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 keycloak_quarkus_http_management_port: 9000 +keycloak_quarkus_jgroups_ip: "{{ ansible_default_ipv4.address }}" keycloak_quarkus_jgroups_port: 7800 keycloak_quarkus_java_heap_opts: "-Xms1024m -Xmx2048m" keycloak_quarkus_java_jvm_opts: "-XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 6b0b8c2..cdf280b 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -195,6 +195,10 @@ argument_specs: default: 9000 description: "Port of the management interface. Relevant only when something is exposed on the management interface - see the guide for details." type: "int" + keycloak_quarkus_jgroups_ip: + default: "{{ ansible_default_ipv4.address }}" + description: Host jgroups IP. If changing this variable you must make sure it is always set for all hosts in your cluster. + type: "str" keycloak_quarkus_jgroups_port: default: 7800 description: "jgroups cluster tcp port" diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index cca6764..5c7126d 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -39,8 +39,8 @@ { "name": item, "address": 'jgroups-' + item, - "inventory_host": hostvars[item].ansible_default_ipv4.address | default(item) + '[' + (keycloak_quarkus_jgroups_port | string) + ']', - "value": hostvars[item].ansible_default_ipv4.address | default(item) + "inventory_host": hostvars[item].keycloak_quarkus_jgroups_ip | default(item) + '[' + (keycloak_quarkus_jgroups_port | string) + ']', + "value": hostvars[item].keycloak_quarkus_jgroups_ip | default(item) } ] }} loop: "{{ ansible_play_batch }}" From a70aece0d9e1ac698d48221701a4d2754546544c Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 19 May 2025 14:10:29 +0200 Subject: [PATCH 361/376] chore: RHBK v26.2: Update recommended JDBC driver versions --- roles/keycloak_quarkus/defaults/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index b4d5a37..8b7c16d 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -125,19 +125,19 @@ keycloak_quarkus_db_user: keycloak-user keycloak_quarkus_db_pass: keycloak-pass keycloak_quarkus_db_url: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].url }}" keycloak_quarkus_db_driver_version: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].version }}" -# override the variables above, following defaults show minimum supported versions +# override the variables above, following defaults show recommended version as per +# https://access.redhat.com/articles/7033107 keycloak_quarkus_default_jdbc: postgres: url: 'jdbc:postgresql://localhost:5432/keycloak' - version: 9.4.1212 + version: 42.7.5 mariadb: url: 'jdbc:mariadb://localhost:3306/keycloak' - version: 2.7.4 + version: 3.5.2 mssql: url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;' version: 12.8.1 driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.8.1.jre11/mssql-jdbc-12.8.1.jre11.jar" - # cf. https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/server_configuration_guide/index#db-installing-the-microsoft-sql-server-driver ### logging configuration keycloak_quarkus_log: file keycloak_quarkus_log_level: info From 8093b1af2acea4dcc854f2164eefbb53c8c28089 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 19 May 2025 14:10:45 +0200 Subject: [PATCH 362/376] chore: RHBK v26.2: Bump RHBK version to v26.2.4 --- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index cdf280b..0f437b7 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -475,7 +475,7 @@ argument_specs: downstream: options: rhbk_version: - default: "26.0.11" + default: "26.2.4" description: "Red Hat Build of Keycloak version" type: "str" rhbk_archive: From f8c75de5d5f822cb0b3cfd6cccecd562ca658f92 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 19 May 2025 14:12:50 +0200 Subject: [PATCH 363/376] chore: RHBK v26.2: Bump KC version to v26.2.4 --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/meta/argument_specs.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 7aedb45..2460674 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -33,7 +33,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `26.0.7` | +|`keycloak_quarkus_version`| keycloak.org package version | `26.2.4` | |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 8b7c16d..cbea292 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 26.0.8 +keycloak_quarkus_version: 26.2.4 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 0f437b7..95d42f4 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -2,7 +2,7 @@ argument_specs: main: options: keycloak_quarkus_version: - default: "26.0.8" + default: "26.2.4" description: "keycloak.org package version" type: "str" keycloak_quarkus_archive: From 8f95bcb9e67250ad0cf332fd3cbfa73d584c53b8 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 19 May 2025 14:38:45 +0200 Subject: [PATCH 364/376] feat(HA): Change default ispn discovery mechanism to JDBCPING as per v26.2.* (#282) --- roles/keycloak_quarkus/README.md | 2 +- roles/keycloak_quarkus/defaults/main.yml | 2 +- roles/keycloak_quarkus/templates/cache-ispn.xml.j2 | 14 +++++++++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 2460674..0da7272 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -77,7 +77,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| |`keycloak_quarkus_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` | -|`keycloak_quarkus_ha_discovery`| Discovery protocol for HA cluster members | `TCPPING` | +|`keycloak_quarkus_ha_discovery`| Discovery protocol for HA cluster members | `JDBCPING` | |`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` | |`keycloak_quarkus_jgroups_ip`| Host jgroups IP. If changing this variable you must make sure it is always set for all hosts in your cluster. | `{{ ansible_default_ipv4.address }}` | |`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7800` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index cbea292..ee12214 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -70,7 +70,7 @@ keycloak_quarkus_config_key_store_password: '' ### Enable configuration for database backend, clustering and remote caches on infinispan keycloak_quarkus_ha_enabled: false -keycloak_quarkus_ha_discovery: "TCPPING" +keycloak_quarkus_ha_discovery: "JDBCPING" ### Enable database configuration, must be enabled when HA is configured keycloak_quarkus_db_enabled: "{{ keycloak_quarkus_ha_enabled }}" keycloak_quarkus_systemd_wait_for_port: "{{ keycloak_quarkus_ha_enabled }}" diff --git a/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 index e546ab8..2d745d5 100644 --- a/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 +++ b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 @@ -22,7 +22,8 @@ xmlns="urn:infinispan:config:15.0"> {% set stack_expression='' %} -{% if keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING' %} +{% if keycloak_quarkus_ha_enabled %} +{% if keycloak_quarkus_ha_discovery == 'TCPPING' %} {% set stack_expression='stack="tcpping"' %} @@ -35,6 +36,9 @@ /> +{% elif keycloak_quarkus_ha_discovery == 'JDBCPING' %} +{% set stack_expression='stack="JDBC_PING2"' %} +{% endif %} {% endif %} @@ -93,6 +97,14 @@
+ + + + + + + + From d23ae39c258989a88ca2474bdf74502612bb2cf4 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Mon, 19 May 2025 14:44:06 +0200 Subject: [PATCH 365/376] chore(molecule): RHBK v26.2 (#282) --- molecule/default/prepare.yml | 2 +- molecule/quarkus/converge.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index 77a7723..44d4a91 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -18,7 +18,7 @@ - name: Download keycloak archive to controller directory ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user - url: https://github.com/keycloak/keycloak/releases/download/26.0.8/keycloak-26.0.8.zip + url: https://github.com/keycloak/keycloak/releases/download/26.2.4/keycloak-26.2.4.zip dest: /tmp/keycloak mode: '0640' delegate_to: localhost diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 65da7bd..1114478 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -23,7 +23,7 @@ keycloak_quarkus_systemd_wait_for_delay: 2 keycloak_quarkus_systemd_wait_for_log: true keycloak_quarkus_restart_health_check: false # would fail because of self-signed cert - keycloak_quarkus_version: 26.2.0 + keycloak_quarkus_version: 26.2.4 keycloak_quarkus_additional_env_vars: - key: KC_FEATURES_DISABLED value: impersonation,kerberos @@ -45,7 +45,7 @@ repository_url: https://repo1.maven.org/maven2/ # https://mvnrepository.com/artifact/org.keycloak/keycloak-kerberos-federation/24.0.4 group_id: org.keycloak artifact_id: keycloak-kerberos-federation - version: 26.0.7 # optional + version: 26.2.4 # optional # username: myUser # optional # password: myPAT # optional # - id: my-static-theme From 0a5fc3ae25137413283af34a69fa8cae1706f4fc Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 20 May 2025 10:35:01 +0200 Subject: [PATCH 366/376] restructure molecule tests --- .github/workflows/ci.yml | 13 +- molecule/quarkus_ha_remote/converge.yml | 29 + molecule/quarkus_ha_remote/molecule.yml | 104 +++ .../postgresql/postgresql.conf | 750 ++++++++++++++++++ molecule/quarkus_ha_remote/prepare.yml | 44 + molecule/quarkus_ha_remote/roles | 1 + molecule/quarkus_ha_remote/verify.yml | 29 + 7 files changed, 968 insertions(+), 2 deletions(-) create mode 100644 molecule/quarkus_ha_remote/converge.yml create mode 100644 molecule/quarkus_ha_remote/molecule.yml create mode 100644 molecule/quarkus_ha_remote/postgresql/postgresql.conf create mode 100644 molecule/quarkus_ha_remote/prepare.yml create mode 120000 molecule/quarkus_ha_remote/roles create mode 100644 molecule/quarkus_ha_remote/verify.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index de65d72..16b6802 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,14 +6,23 @@ on: - main pull_request: workflow_dispatch: + inputs: + debug_verbosity: + description: 'ANSIBLE_VERBOSITY envvar value' + required: false schedule: - cron: '15 6 * * *' jobs: ci: - uses: ansible-middleware/github-actions/.github/workflows/ci.yml@main + uses: ansible-middleware/github-actions/.github/workflows/cish.yml@main secrets: inherit with: fqcn: 'middleware_automation/keycloak' + debug_verbosity: "${{ github.event.inputs.debug_verbosity }}" molecule_tests: >- - [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode", "quarkus_upgrade", "debian", "quarkus_ha" ] + [ "default", "debian", "quarkus_ha", "quarkus_ha_remote" ] + podman_tests_current: >- + [ "default", "quarkus", "quarkus-devmode", "quarkus_upgrade" ] + podman_tests_next: >- + [ "default", "quarkus", "quarkus-devmode", "quarkus_upgrade" ] diff --git a/molecule/quarkus_ha_remote/converge.yml b/molecule/quarkus_ha_remote/converge.yml new file mode 100644 index 0000000..fa5314f --- /dev/null +++ b/molecule/quarkus_ha_remote/converge.yml @@ -0,0 +1,29 @@ +--- +- name: Converge + hosts: keycloak + vars: + keycloak_quarkus_show_deprecation_warnings: false + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" + keycloak_quarkus_hostname: "http://{{ inventory_hostname }}:8080" + keycloak_quarkus_log: file + keycloak_quarkus_log_level: info + keycloak_quarkus_https_key_file_enabled: true + keycloak_quarkus_key_file_copy_enabled: true + keycloak_quarkus_key_content: "{{ lookup('file', inventory_hostname + '.key') }}" + keycloak_quarkus_cert_file_copy_enabled: true + keycloak_quarkus_cert_file_src: "{{ inventory_hostname }}.pem" + keycloak_quarkus_ks_vault_enabled: true + keycloak_quarkus_ks_vault_file: "/opt/keycloak/vault/keystore.p12" + keycloak_quarkus_ks_vault_pass: keystorepassword + keycloak_quarkus_systemd_wait_for_port: true + keycloak_quarkus_systemd_wait_for_timeout: 20 + keycloak_quarkus_systemd_wait_for_delay: 2 + keycloak_quarkus_systemd_wait_for_log: true + keycloak_quarkus_ha_enabled: true + keycloak_quarkus_restart_strategy: restart/serial.yml + keycloak_quarkus_db_user: keycloak + keycloak_quarkus_db_pass: mysecretpass + keycloak_quarkus_db_url: jdbc:postgresql://postgres:5432/keycloak + roles: + - role: keycloak_quarkus diff --git a/molecule/quarkus_ha_remote/molecule.yml b/molecule/quarkus_ha_remote/molecule.yml new file mode 100644 index 0000000..673b021 --- /dev/null +++ b/molecule/quarkus_ha_remote/molecule.yml @@ -0,0 +1,104 @@ +--- +driver: + name: docker +platforms: + - name: instance1 + image: registry.access.redhat.com/ubi9/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + groups: + - keycloak + networks: + - name: rhbk + port_bindings: + - "8080/tcp" + - "8443/tcp" + - "9000/tcp" + - name: instance2 + image: registry.access.redhat.com/ubi9/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + groups: + - keycloak + networks: + - name: rhbk + port_bindings: + - "8080/tcp" + - "8443/tcp" + - "9000/tcp" + - name: infinispan1 + image: registry.access.redhat.com/ubi9/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + groups: + - infinispan + networks: + - name: rhbk + port_bindings: + - "11222/tcp" + - name: infinispan2 + image: registry.access.redhat.com/ubi9/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + groups: + - infinispan + networks: + - name: rhbk + port_bindings: + - "11222/tcp" + - name: postgres + image: ubuntu/postgres:14-22.04_beta + pre_build_image: true + privileged: true + command: postgres + groups: + - database + networks: + - name: rhbk + port_bindings: + - "5432/tcp" + mounts: + - type: bind + target: /etc/postgresql/postgresql.conf + source: ${PWD}/molecule/quarkus_ha/postgresql/postgresql.conf + env: + POSTGRES_USER: keycloak + POSTGRES_PASSWORD: mysecretpass + POSTGRES_DB: keycloak + POSTGRES_HOST_AUTH_METHOD: trust +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + ssh_connection: + pipelining: false + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + env: + ANSIBLE_FORCE_COLOR: "true" + PYTHONHTTPSVERIFY: 0 +verifier: + name: ansible +scenario: + test_sequence: + - cleanup + - destroy + - create + - prepare + - converge + - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/quarkus_ha_remote/postgresql/postgresql.conf b/molecule/quarkus_ha_remote/postgresql/postgresql.conf new file mode 100644 index 0000000..d702576 --- /dev/null +++ b/molecule/quarkus_ha_remote/postgresql/postgresql.conf @@ -0,0 +1,750 @@ +# ----------------------------- +# PostgreSQL configuration file +# ----------------------------- +# +# This file consists of lines of the form: +# +# name = value +# +# (The "=" is optional.) Whitespace may be used. Comments are introduced with +# "#" anywhere on a line. The complete list of parameter names and allowed +# values can be found in the PostgreSQL documentation. +# +# The commented-out settings shown in this file represent the default values. +# Re-commenting a setting is NOT sufficient to revert it to the default value; +# you need to reload the server. +# +# This file is read on server startup and when the server receives a SIGHUP +# signal. If you edit the file on a running system, you have to SIGHUP the +# server for the changes to take effect, run "pg_ctl reload", or execute +# "SELECT pg_reload_conf()". Some parameters, which are marked below, +# require a server shutdown and restart to take effect. +# +# Any parameter can also be given as a command-line option to the server, e.g., +# "postgres -c log_connections=on". Some parameters can be changed at run time +# with the "SET" SQL command. +# +# Memory units: kB = kilobytes Time units: ms = milliseconds +# MB = megabytes s = seconds +# GB = gigabytes min = minutes +# TB = terabytes h = hours +# d = days + + +#------------------------------------------------------------------------------ +# FILE LOCATIONS +#------------------------------------------------------------------------------ + +# The default values of these variables are driven from the -D command-line +# option or PGDATA environment variable, represented here as ConfigDir. + +#data_directory = 'ConfigDir' # use data in another directory + # (change requires restart) +#hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file + # (change requires restart) +#ident_file = 'ConfigDir/pg_ident.conf' # ident configuration file + # (change requires restart) + +# If external_pid_file is not explicitly set, no extra PID file is written. +#external_pid_file = '' # write an extra PID file + # (change requires restart) + + +#------------------------------------------------------------------------------ +# CONNECTIONS AND AUTHENTICATION +#------------------------------------------------------------------------------ + +# - Connection Settings - + +listen_addresses = '*' # what IP address(es) to listen on; + # comma-separated list of addresses; + # defaults to 'localhost'; use '*' for all + # (change requires restart) +#port = 5432 # (change requires restart) +#max_connections = 100 # (change requires restart) +#superuser_reserved_connections = 3 # (change requires restart) +#unix_socket_directories = '/tmp' # comma-separated list of directories + # (change requires restart) +#unix_socket_group = '' # (change requires restart) +#unix_socket_permissions = 0777 # begin with 0 to use octal notation + # (change requires restart) +#bonjour = off # advertise server via Bonjour + # (change requires restart) +#bonjour_name = '' # defaults to the computer name + # (change requires restart) + +# - TCP settings - +# see "man 7 tcp" for details + +#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; + # 0 selects the system default +#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; + # 0 selects the system default +#tcp_keepalives_count = 0 # TCP_KEEPCNT; + # 0 selects the system default +#tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds; + # 0 selects the system default + +# - Authentication - + +#authentication_timeout = 1min # 1s-600s +#password_encryption = md5 # md5 or scram-sha-256 +#db_user_namespace = off + +# GSSAPI using Kerberos +#krb_server_keyfile = '' +#krb_caseins_users = off + +# - SSL - + +#ssl = off +#ssl_ca_file = '' +#ssl_cert_file = 'server.crt' +#ssl_crl_file = '' +#ssl_key_file = 'server.key' +#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers +#ssl_prefer_server_ciphers = on +#ssl_ecdh_curve = 'prime256v1' +#ssl_min_protocol_version = 'TLSv1' +#ssl_max_protocol_version = '' +#ssl_dh_params_file = '' +#ssl_passphrase_command = '' +#ssl_passphrase_command_supports_reload = off + + +#------------------------------------------------------------------------------ +# RESOURCE USAGE (except WAL) +#------------------------------------------------------------------------------ + +# - Memory - + +#shared_buffers = 32MB # min 128kB + # (change requires restart) +#huge_pages = try # on, off, or try + # (change requires restart) +#temp_buffers = 8MB # min 800kB +#max_prepared_transactions = 0 # zero disables the feature + # (change requires restart) +# Caution: it is not advisable to set max_prepared_transactions nonzero unless +# you actively intend to use prepared transactions. +#work_mem = 4MB # min 64kB +#maintenance_work_mem = 64MB # min 1MB +#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem +#max_stack_depth = 2MB # min 100kB +#shared_memory_type = mmap # the default is the first option + # supported by the operating system: + # mmap + # sysv + # windows + # (change requires restart) +#dynamic_shared_memory_type = posix # the default is the first option + # supported by the operating system: + # posix + # sysv + # windows + # mmap + # (change requires restart) + +# - Disk - + +#temp_file_limit = -1 # limits per-process temp file space + # in kB, or -1 for no limit + +# - Kernel Resources - + +#max_files_per_process = 1000 # min 25 + # (change requires restart) + +# - Cost-Based Vacuum Delay - + +#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables) +#vacuum_cost_page_hit = 1 # 0-10000 credits +#vacuum_cost_page_miss = 10 # 0-10000 credits +#vacuum_cost_page_dirty = 20 # 0-10000 credits +#vacuum_cost_limit = 200 # 1-10000 credits + +# - Background Writer - + +#bgwriter_delay = 200ms # 10-10000ms between rounds +#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables +#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round +#bgwriter_flush_after = 0 # measured in pages, 0 disables + +# - Asynchronous Behavior - + +#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching +#max_worker_processes = 8 # (change requires restart) +#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers +#max_parallel_workers_per_gather = 2 # taken from max_parallel_workers +#parallel_leader_participation = on +#max_parallel_workers = 8 # maximum number of max_worker_processes that + # can be used in parallel operations +#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate + # (change requires restart) +#backend_flush_after = 0 # measured in pages, 0 disables + + +#------------------------------------------------------------------------------ +# WRITE-AHEAD LOG +#------------------------------------------------------------------------------ + +# - Settings - + +#wal_level = replica # minimal, replica, or logical + # (change requires restart) +#fsync = on # flush data to disk for crash safety + # (turning this off can cause + # unrecoverable data corruption) +#synchronous_commit = on # synchronization level; + # off, local, remote_write, remote_apply, or on +#wal_sync_method = fsync # the default is the first option + # supported by the operating system: + # open_datasync + # fdatasync (default on Linux) + # fsync + # fsync_writethrough + # open_sync +#full_page_writes = on # recover from partial page writes +#wal_compression = off # enable compression of full-page writes +#wal_log_hints = off # also do full page writes of non-critical updates + # (change requires restart) +#wal_init_zero = on # zero-fill new WAL files +#wal_recycle = on # recycle WAL files +#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers + # (change requires restart) +#wal_writer_delay = 200ms # 1-10000 milliseconds +#wal_writer_flush_after = 1MB # measured in pages, 0 disables + +#commit_delay = 0 # range 0-100000, in microseconds +#commit_siblings = 5 # range 1-1000 + +# - Checkpoints - + +#checkpoint_timeout = 5min # range 30s-1d +#max_wal_size = 1GB +#min_wal_size = 80MB +#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0 +#checkpoint_flush_after = 0 # measured in pages, 0 disables +#checkpoint_warning = 30s # 0 disables + +# - Archiving - + +#archive_mode = off # enables archiving; off, on, or always + # (change requires restart) +#archive_command = '' # command to use to archive a logfile segment + # placeholders: %p = path of file to archive + # %f = file name only + # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' +#archive_timeout = 0 # force a logfile segment switch after this + # number of seconds; 0 disables + +# - Archive Recovery - + +# These are only used in recovery mode. + +#restore_command = '' # command to use to restore an archived logfile segment + # placeholders: %p = path of file to restore + # %f = file name only + # e.g. 'cp /mnt/server/archivedir/%f %p' + # (change requires restart) +#archive_cleanup_command = '' # command to execute at every restartpoint +#recovery_end_command = '' # command to execute at completion of recovery + +# - Recovery Target - + +# Set these only when performing a targeted recovery. + +#recovery_target = '' # 'immediate' to end recovery as soon as a + # consistent state is reached + # (change requires restart) +#recovery_target_name = '' # the named restore point to which recovery will proceed + # (change requires restart) +#recovery_target_time = '' # the time stamp up to which recovery will proceed + # (change requires restart) +#recovery_target_xid = '' # the transaction ID up to which recovery will proceed + # (change requires restart) +#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed + # (change requires restart) +#recovery_target_inclusive = on # Specifies whether to stop: + # just after the specified recovery target (on) + # just before the recovery target (off) + # (change requires restart) +#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID + # (change requires restart) +#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown' + # (change requires restart) + + +#------------------------------------------------------------------------------ +# REPLICATION +#------------------------------------------------------------------------------ + +# - Sending Servers - + +# Set these on the master and on any standby that will send replication data. + +#max_wal_senders = 10 # max number of walsender processes + # (change requires restart) +#wal_keep_segments = 0 # in logfile segments; 0 disables +#wal_sender_timeout = 60s # in milliseconds; 0 disables + +#max_replication_slots = 10 # max number of replication slots + # (change requires restart) +#track_commit_timestamp = off # collect timestamp of transaction commit + # (change requires restart) + +# - Master Server - + +# These settings are ignored on a standby server. + +#synchronous_standby_names = '' # standby servers that provide sync rep + # method to choose sync standbys, number of sync standbys, + # and comma-separated list of application_name + # from standby(s); '*' = all +#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed + +# - Standby Servers - + +# These settings are ignored on a master server. + +#primary_conninfo = '' # connection string to sending server + # (change requires restart) +#primary_slot_name = '' # replication slot on sending server + # (change requires restart) +#promote_trigger_file = '' # file name whose presence ends recovery +#hot_standby = on # "off" disallows queries during recovery + # (change requires restart) +#max_standby_archive_delay = 30s # max delay before canceling queries + # when reading WAL from archive; + # -1 allows indefinite delay +#max_standby_streaming_delay = 30s # max delay before canceling queries + # when reading streaming WAL; + # -1 allows indefinite delay +#wal_receiver_status_interval = 10s # send replies at least this often + # 0 disables +#hot_standby_feedback = off # send info from standby to prevent + # query conflicts +#wal_receiver_timeout = 60s # time that receiver waits for + # communication from master + # in milliseconds; 0 disables +#wal_retrieve_retry_interval = 5s # time to wait before retrying to + # retrieve WAL after a failed attempt +#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery + +# - Subscribers - + +# These settings are ignored on a publisher. + +#max_logical_replication_workers = 4 # taken from max_worker_processes + # (change requires restart) +#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers + + +#------------------------------------------------------------------------------ +# QUERY TUNING +#------------------------------------------------------------------------------ + +# - Planner Method Configuration - + +#enable_bitmapscan = on +#enable_hashagg = on +#enable_hashjoin = on +#enable_indexscan = on +#enable_indexonlyscan = on +#enable_material = on +#enable_mergejoin = on +#enable_nestloop = on +#enable_parallel_append = on +#enable_seqscan = on +#enable_sort = on +#enable_tidscan = on +#enable_partitionwise_join = off +#enable_partitionwise_aggregate = off +#enable_parallel_hash = on +#enable_partition_pruning = on + +# - Planner Cost Constants - + +#seq_page_cost = 1.0 # measured on an arbitrary scale +#random_page_cost = 4.0 # same scale as above +#cpu_tuple_cost = 0.01 # same scale as above +#cpu_index_tuple_cost = 0.005 # same scale as above +#cpu_operator_cost = 0.0025 # same scale as above +#parallel_tuple_cost = 0.1 # same scale as above +#parallel_setup_cost = 1000.0 # same scale as above + +#jit_above_cost = 100000 # perform JIT compilation if available + # and query more expensive than this; + # -1 disables +#jit_inline_above_cost = 500000 # inline small functions if query is + # more expensive than this; -1 disables +#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if + # query is more expensive than this; + # -1 disables + +#min_parallel_table_scan_size = 8MB +#min_parallel_index_scan_size = 512kB +#effective_cache_size = 4GB + +# - Genetic Query Optimizer - + +#geqo = on +#geqo_threshold = 12 +#geqo_effort = 5 # range 1-10 +#geqo_pool_size = 0 # selects default based on effort +#geqo_generations = 0 # selects default based on effort +#geqo_selection_bias = 2.0 # range 1.5-2.0 +#geqo_seed = 0.0 # range 0.0-1.0 + +# - Other Planner Options - + +#default_statistics_target = 100 # range 1-10000 +#constraint_exclusion = partition # on, off, or partition +#cursor_tuple_fraction = 0.1 # range 0.0-1.0 +#from_collapse_limit = 8 +#join_collapse_limit = 8 # 1 disables collapsing of explicit + # JOIN clauses +#force_parallel_mode = off +#jit = on # allow JIT compilation +#plan_cache_mode = auto # auto, force_generic_plan or + # force_custom_plan + + +#------------------------------------------------------------------------------ +# REPORTING AND LOGGING +#------------------------------------------------------------------------------ + +# - Where to Log - + +#log_destination = 'stderr' # Valid values are combinations of + # stderr, csvlog, syslog, and eventlog, + # depending on platform. csvlog + # requires logging_collector to be on. + +# This is used when logging to stderr: +#logging_collector = off # Enable capturing of stderr and csvlog + # into log files. Required to be on for + # csvlogs. + # (change requires restart) + +# These are only used if logging_collector is on: +#log_directory = 'log' # directory where log files are written, + # can be absolute or relative to PGDATA +#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern, + # can include strftime() escapes +#log_file_mode = 0600 # creation mode for log files, + # begin with 0 to use octal notation +#log_truncate_on_rotation = off # If on, an existing log file with the + # same name as the new log file will be + # truncated rather than appended to. + # But such truncation only occurs on + # time-driven rotation, not on restarts + # or size-driven rotation. Default is + # off, meaning append to existing files + # in all cases. +#log_rotation_age = 1d # Automatic rotation of logfiles will + # happen after that time. 0 disables. +#log_rotation_size = 10MB # Automatic rotation of logfiles will + # happen after that much log output. + # 0 disables. + +# These are relevant when logging to syslog: +#syslog_facility = 'LOCAL0' +#syslog_ident = 'postgres' +#syslog_sequence_numbers = on +#syslog_split_messages = on + +# This is only relevant when logging to eventlog (win32): +# (change requires restart) +#event_source = 'PostgreSQL' + +# - When to Log - + +#log_min_messages = warning # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic + +#log_min_error_statement = error # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic (effectively off) + +#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements + # and their durations, > 0 logs only + # statements running at least this number + # of milliseconds + +#log_transaction_sample_rate = 0.0 # Fraction of transactions whose statements + # are logged regardless of their duration. 1.0 logs all + # statements from all transactions, 0.0 never logs. + +# - What to Log - + +#debug_print_parse = off +#debug_print_rewritten = off +#debug_print_plan = off +#debug_pretty_print = on +#log_checkpoints = off +#log_connections = off +#log_disconnections = off +#log_duration = off +#log_error_verbosity = default # terse, default, or verbose messages +#log_hostname = off +#log_line_prefix = '%m [%p] ' # special values: + # %a = application name + # %u = user name + # %d = database name + # %r = remote host and port + # %h = remote host + # %p = process ID + # %t = timestamp without milliseconds + # %m = timestamp with milliseconds + # %n = timestamp with milliseconds (as a Unix epoch) + # %i = command tag + # %e = SQL state + # %c = session ID + # %l = session line number + # %s = session start timestamp + # %v = virtual transaction ID + # %x = transaction ID (0 if none) + # %q = stop here in non-session + # processes + # %% = '%' + # e.g. '<%u%%%d> ' +#log_lock_waits = off # log lock waits >= deadlock_timeout +#log_statement = 'none' # none, ddl, mod, all +#log_replication_commands = off +#log_temp_files = -1 # log temporary files equal or larger + # than the specified size in kilobytes; + # -1 disables, 0 logs all temp files +#log_timezone = 'GMT' + +#------------------------------------------------------------------------------ +# PROCESS TITLE +#------------------------------------------------------------------------------ + +#cluster_name = '' # added to process titles if nonempty + # (change requires restart) +#update_process_title = on + + +#------------------------------------------------------------------------------ +# STATISTICS +#------------------------------------------------------------------------------ + +# - Query and Index Statistics Collector - + +#track_activities = on +#track_counts = on +#track_io_timing = off +#track_functions = none # none, pl, all +#track_activity_query_size = 1024 # (change requires restart) +#stats_temp_directory = 'pg_stat_tmp' + + +# - Monitoring - + +#log_parser_stats = off +#log_planner_stats = off +#log_executor_stats = off +#log_statement_stats = off + + +#------------------------------------------------------------------------------ +# AUTOVACUUM +#------------------------------------------------------------------------------ + +#autovacuum = on # Enable autovacuum subprocess? 'on' + # requires track_counts to also be on. +#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and + # their durations, > 0 logs only + # actions running at least this number + # of milliseconds. +#autovacuum_max_workers = 3 # max number of autovacuum subprocesses + # (change requires restart) +#autovacuum_naptime = 1min # time between autovacuum runs +#autovacuum_vacuum_threshold = 50 # min number of row updates before + # vacuum +#autovacuum_analyze_threshold = 50 # min number of row updates before + # analyze +#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum +#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze +#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum + # (change requires restart) +#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age + # before forced vacuum + # (change requires restart) +#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for + # autovacuum, in milliseconds; + # -1 means use vacuum_cost_delay +#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for + # autovacuum, -1 means use + # vacuum_cost_limit + + +#------------------------------------------------------------------------------ +# CLIENT CONNECTION DEFAULTS +#------------------------------------------------------------------------------ + +# - Statement Behavior - + +#client_min_messages = notice # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # log + # notice + # warning + # error +#search_path = '"$user", public' # schema names +#row_security = on +#default_tablespace = '' # a tablespace name, '' uses the default +#temp_tablespaces = '' # a list of tablespace names, '' uses + # only default tablespace +#default_table_access_method = 'heap' +#check_function_bodies = on +#default_transaction_isolation = 'read committed' +#default_transaction_read_only = off +#default_transaction_deferrable = off +#session_replication_role = 'origin' +#statement_timeout = 0 # in milliseconds, 0 is disabled +#lock_timeout = 0 # in milliseconds, 0 is disabled +#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled +#vacuum_freeze_min_age = 50000000 +#vacuum_freeze_table_age = 150000000 +#vacuum_multixact_freeze_min_age = 5000000 +#vacuum_multixact_freeze_table_age = 150000000 +#vacuum_cleanup_index_scale_factor = 0.1 # fraction of total number of tuples + # before index cleanup, 0 always performs + # index cleanup +#bytea_output = 'hex' # hex, escape +#xmlbinary = 'base64' +#xmloption = 'content' +#gin_fuzzy_search_limit = 0 +#gin_pending_list_limit = 4MB + +# - Locale and Formatting - + +#datestyle = 'iso, mdy' +#intervalstyle = 'postgres' +#timezone = 'GMT' +#timezone_abbreviations = 'Default' # Select the set of available time zone + # abbreviations. Currently, there are + # Default + # Australia (historical usage) + # India + # You can create your own file in + # share/timezonesets/. +#extra_float_digits = 1 # min -15, max 3; any value >0 actually + # selects precise output mode +#client_encoding = sql_ascii # actually, defaults to database + # encoding + +# These settings are initialized by initdb, but they can be changed. +#lc_messages = 'C' # locale for system error message + # strings +#lc_monetary = 'C' # locale for monetary formatting +#lc_numeric = 'C' # locale for number formatting +#lc_time = 'C' # locale for time formatting + +# default configuration for text search +#default_text_search_config = 'pg_catalog.simple' + +# - Shared Library Preloading - + +#shared_preload_libraries = '' # (change requires restart) +#local_preload_libraries = '' +#session_preload_libraries = '' +#jit_provider = 'llvmjit' # JIT library to use + +# - Other Defaults - + +#dynamic_library_path = '$libdir' + + +#------------------------------------------------------------------------------ +# LOCK MANAGEMENT +#------------------------------------------------------------------------------ + +#deadlock_timeout = 1s +#max_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_relation = -2 # negative values mean + # (max_pred_locks_per_transaction + # / -max_pred_locks_per_relation) - 1 +#max_pred_locks_per_page = 2 # min 0 + + +#------------------------------------------------------------------------------ +# VERSION AND PLATFORM COMPATIBILITY +#------------------------------------------------------------------------------ + +# - Previous PostgreSQL Versions - + +#array_nulls = on +#backslash_quote = safe_encoding # on, off, or safe_encoding +#escape_string_warning = on +#lo_compat_privileges = off +#operator_precedence_warning = off +#quote_all_identifiers = off +#standard_conforming_strings = on +#synchronize_seqscans = on + +# - Other Platforms and Clients - + +#transform_null_equals = off + + +#------------------------------------------------------------------------------ +# ERROR HANDLING +#------------------------------------------------------------------------------ + +#exit_on_error = off # terminate session on any error? +#restart_after_crash = on # reinitialize after backend crash? +#data_sync_retry = off # retry or panic on failure to fsync + # data? + # (change requires restart) + + +#------------------------------------------------------------------------------ +# CONFIG FILE INCLUDES +#------------------------------------------------------------------------------ + +# These options allow settings to be loaded from files other than the +# default postgresql.conf. Note that these are directives, not variable +# assignments, so they can usefully be given more than once. + +#include_dir = '...' # include files ending in '.conf' from + # a directory, e.g., 'conf.d' +#include_if_exists = '...' # include file only if it exists +#include = '...' # include file + + +#------------------------------------------------------------------------------ +# CUSTOMIZED OPTIONS +#------------------------------------------------------------------------------ + +# Add settings for extensions here diff --git a/molecule/quarkus_ha_remote/prepare.yml b/molecule/quarkus_ha_remote/prepare.yml new file mode 100644 index 0000000..dff1821 --- /dev/null +++ b/molecule/quarkus_ha_remote/prepare.yml @@ -0,0 +1,44 @@ +--- +- name: Prepare + hosts: keycloak + tasks: + - name: "Display hera_home if defined." + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - name: "Ensure common prepare phase are set." + ansible.builtin.include_tasks: ../prepare.yml + + - name: Create certificate request + ansible.builtin.command: "openssl req -x509 -newkey rsa:4096 -keyout {{ inventory_hostname }}.key -out {{ inventory_hostname }}.pem -sha256 -days 365 -nodes -subj '/CN={{ inventory_hostname }}'" + delegate_to: localhost + changed_when: False + + - name: Create vault directory + become: true + ansible.builtin.file: + state: directory + path: "/opt/keycloak/vault" + mode: 0755 + + - name: Make sure a jre is available (for keytool to prepare keystore) + delegate_to: localhost + ansible.builtin.package: + name: "{{ 'java-17-openjdk-headless' if hera_home | length > 0 else 'openjdk-17-jdk-headless' }}" + state: present + become: true + failed_when: false + + - name: Create vault keystore + ansible.builtin.command: keytool -importpass -alias TestRealm_testalias -keystore keystore.p12 -storepass keystorepassword + delegate_to: localhost + register: keytool_cmd + changed_when: False + failed_when: not 'already exists' in keytool_cmd.stdout and keytool_cmd.rc != 0 + + - name: Copy certificates and vault + become: true + ansible.builtin.copy: + src: keystore.p12 + dest: /opt/keycloak/vault/keystore.p12 + mode: 0444 diff --git a/molecule/quarkus_ha_remote/roles b/molecule/quarkus_ha_remote/roles new file mode 120000 index 0000000..b741aa3 --- /dev/null +++ b/molecule/quarkus_ha_remote/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/molecule/quarkus_ha_remote/verify.yml b/molecule/quarkus_ha_remote/verify.yml new file mode 100644 index 0000000..c1a2fb9 --- /dev/null +++ b/molecule/quarkus_ha_remote/verify.yml @@ -0,0 +1,29 @@ +--- +- name: Verify + hosts: keycloak + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + + - name: Check if keycloak service started + ansible.builtin.assert: + that: + - ansible_facts.services["keycloak.service"]["state"] == "running" + - ansible_facts.services["keycloak.service"]["status"] == "enabled" + fail_msg: "Service not running" + + - name: Set internal envvar + ansible.builtin.set_fact: + hera_home: "{{ lookup('env', 'HERA_HOME') }}" + + - name: Check log file + become: true + ansible.builtin.stat: + path: /var/log/keycloak/keycloak.log + register: keycloak_log_file + + - name: Check if keycloak file exists + ansible.builtin.assert: + that: + - keycloak_log_file.stat.exists + - not keycloak_log_file.stat.isdir From 88e4ea8d9907bf68a4c57e88b516ea6442f408d6 Mon Sep 17 00:00:00 2001 From: Helmut Wolf Date: Tue, 20 May 2025 13:51:47 +0200 Subject: [PATCH 367/376] fix: MVN provider invokes KC config rebuild --- roles/keycloak_quarkus/tasks/install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 4719b64..b188e6c 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -236,7 +236,6 @@ loop: "{{ keycloak_quarkus_providers }}" when: item.maven is defined no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" - notify: "{{ ['invalidate keycloak theme cache', 'rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" - name: "Copy maven providers" ansible.builtin.copy: @@ -250,6 +249,7 @@ loop: "{{ keycloak_quarkus_providers }}" when: item.maven is defined no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" + notify: "{{ ['invalidate keycloak theme cache', 'rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" - name: "Copy local providers" ansible.builtin.copy: From 0403939c038bd49715f7099982f16f833e28b259 Mon Sep 17 00:00:00 2001 From: Ranabir Chakraborty Date: Tue, 20 May 2025 20:59:59 +0530 Subject: [PATCH 368/376] AMW-398 Use tags to decorate the role workflow --- roles/keycloak/tasks/debian.yml | 6 ++++- roles/keycloak/tasks/main.yml | 24 ++++++++++++++--- roles/keycloak/tasks/redhat.yml | 6 ++++- roles/keycloak_quarkus/tasks/debian.yml | 6 ++++- roles/keycloak_quarkus/tasks/main.yml | 36 ++++++++++++++++++++----- roles/keycloak_quarkus/tasks/redhat.yml | 6 ++++- 6 files changed, 70 insertions(+), 14 deletions(-) diff --git a/roles/keycloak/tasks/debian.yml b/roles/keycloak/tasks/debian.yml index ffb1348..acfadcc 100644 --- a/roles/keycloak/tasks/debian.yml +++ b/roles/keycloak/tasks/debian.yml @@ -1,6 +1,10 @@ --- - name: Include firewall config tasks - ansible.builtin.include_tasks: iptables.yml + ansible.builtin.include_tasks: + file: iptables.yml + apply: + tags: + - firewall when: keycloak_configure_iptables tags: - firewall diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index a21f359..f826b63 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -1,22 +1,38 @@ --- # tasks file for keycloak - name: Check prerequisites - ansible.builtin.include_tasks: prereqs.yml + ansible.builtin.include_tasks: + file: prereqs.yml + apply: + tags: + - prereqs tags: - prereqs - name: Distro specific tasks - ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml" + ansible.builtin.include_tasks: + file: "{{ ansible_os_family | lower }}.yml" + apply: + tags: + - unbound tags: - unbound - name: Include install tasks - ansible.builtin.include_tasks: install.yml + ansible.builtin.include_tasks: + file: install.yml + apply: + tags: + - install tags: - install - name: Include systemd tasks - ansible.builtin.include_tasks: systemd.yml + ansible.builtin.include_tasks: + file: systemd.yml + apply: + tags: + - systemd tags: - systemd diff --git a/roles/keycloak/tasks/redhat.yml b/roles/keycloak/tasks/redhat.yml index 596834b..ece5772 100644 --- a/roles/keycloak/tasks/redhat.yml +++ b/roles/keycloak/tasks/redhat.yml @@ -1,6 +1,10 @@ --- - name: Include firewall config tasks - ansible.builtin.include_tasks: firewalld.yml + ansible.builtin.include_tasks: + file: firewalld.yml + apply: + tags: + - firewall when: keycloak_configure_firewalld tags: - firewall diff --git a/roles/keycloak_quarkus/tasks/debian.yml b/roles/keycloak_quarkus/tasks/debian.yml index 4a36661..7e59204 100644 --- a/roles/keycloak_quarkus/tasks/debian.yml +++ b/roles/keycloak_quarkus/tasks/debian.yml @@ -1,6 +1,10 @@ --- - name: Include firewall config tasks - ansible.builtin.include_tasks: iptables.yml + ansible.builtin.include_tasks: + file: iptables.yml + apply: + tags: + - firewall when: keycloak_quarkus_configure_iptables tags: - firewall diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index 5c7126d..6a7a4b0 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -1,34 +1,58 @@ --- # tasks file for keycloak - name: Check prerequisites - ansible.builtin.include_tasks: prereqs.yml + ansible.builtin.include_tasks: + file: prereqs.yml + apply: + tags: + - prereqs tags: - prereqs - always - name: Check for deprecations - ansible.builtin.include_tasks: deprecations.yml + ansible.builtin.include_tasks: + file: deprecations.yml + apply: + tags: + - always tags: - always - name: Distro specific tasks - ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml" + ansible.builtin.include_tasks: + file: "{{ ansible_os_family | lower }}.yml" + apply: + tags: + - unbound tags: - unbound - name: Include install tasks - ansible.builtin.include_tasks: install.yml + ansible.builtin.include_tasks: + file: install.yml + apply: + tags: + - install tags: - install - name: Include systemd tasks - ansible.builtin.include_tasks: systemd.yml + ansible.builtin.include_tasks: + file: systemd.yml + apply: + tags: + - systemd tags: - systemd - name: Include configuration key store tasks + ansible.builtin.include_tasks: + file: config_store.yml + apply: + tags: + - install when: keycloak.config_key_store_enabled - ansible.builtin.include_tasks: config_store.yml tags: - install diff --git a/roles/keycloak_quarkus/tasks/redhat.yml b/roles/keycloak_quarkus/tasks/redhat.yml index 093b930..26d552b 100644 --- a/roles/keycloak_quarkus/tasks/redhat.yml +++ b/roles/keycloak_quarkus/tasks/redhat.yml @@ -1,6 +1,10 @@ --- - name: Include firewall config tasks - ansible.builtin.include_tasks: firewalld.yml + ansible.builtin.include_tasks: + file: firewalld.yml + apply: + tags: + - firewall when: keycloak_quarkus_configure_firewalld tags: - firewall From 476bc0ec0bc8c8eabd2475aa059c01cac2eead9e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Tue, 20 May 2025 10:40:59 +0200 Subject: [PATCH 369/376] update test config --- .github/workflows/ci.yml | 6 +++--- molecule/default/molecule.yml | 4 +++- molecule/quarkus/molecule.yml | 4 +++- molecule/quarkus/prepare.yml | 2 +- molecule/{quarkus-devmode => quarkus_devmode}/converge.yml | 0 molecule/{quarkus-devmode => quarkus_devmode}/molecule.yml | 4 +++- molecule/{quarkus-devmode => quarkus_devmode}/prepare.yml | 0 molecule/{quarkus-devmode => quarkus_devmode}/roles | 0 molecule/{quarkus-devmode => quarkus_devmode}/verify.yml | 0 molecule/quarkus_upgrade/molecule.yml | 6 +++++- 10 files changed, 18 insertions(+), 8 deletions(-) rename molecule/{quarkus-devmode => quarkus_devmode}/converge.yml (100%) rename molecule/{quarkus-devmode => quarkus_devmode}/molecule.yml (93%) rename molecule/{quarkus-devmode => quarkus_devmode}/prepare.yml (100%) rename molecule/{quarkus-devmode => quarkus_devmode}/roles (100%) rename molecule/{quarkus-devmode => quarkus_devmode}/verify.yml (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 16b6802..b9509a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,8 +21,8 @@ jobs: fqcn: 'middleware_automation/keycloak' debug_verbosity: "${{ github.event.inputs.debug_verbosity }}" molecule_tests: >- - [ "default", "debian", "quarkus_ha", "quarkus_ha_remote" ] + [ "debian", "quarkus_ha", "quarkus_ha_remote" ] podman_tests_current: >- - [ "default", "quarkus", "quarkus-devmode", "quarkus_upgrade" ] + [ "default", "quarkus", "quarkus_devmode", "quarkus_upgrade" ] podman_tests_next: >- - [ "default", "quarkus", "quarkus-devmode", "quarkus_upgrade" ] + [ "default", "quarkus", "quarkus_devmode", "quarkus_upgrade" ] diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index 011c08e..587a3c8 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -1,6 +1,6 @@ --- driver: - name: docker + name: podman platforms: - name: instance image: registry.access.redhat.com/ubi9/ubi-init:latest @@ -29,6 +29,8 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" + PROXY: "${PROXY}" + NO_PROXY: "${NO_PROXY}" verifier: name: ansible scenario: diff --git a/molecule/quarkus/molecule.yml b/molecule/quarkus/molecule.yml index cf975e5..1b4c8c5 100644 --- a/molecule/quarkus/molecule.yml +++ b/molecule/quarkus/molecule.yml @@ -1,6 +1,6 @@ --- driver: - name: docker + name: podman platforms: - name: instance image: registry.access.redhat.com/ubi9/ubi-init:latest @@ -32,6 +32,8 @@ provisioner: env: ANSIBLE_FORCE_COLOR: "true" PYTHONHTTPSVERIFY: 0 + PROXY: "${PROXY}" + NO_PROXY: "${NO_PROXY}" verifier: name: ansible scenario: diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index d8ef369..abe2518 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -24,7 +24,7 @@ - name: Make sure a jre is available (for keytool to prepare keystore) delegate_to: localhost ansible.builtin.package: - name: "{{ 'java-21-openjdk-headless' if hera_home | length > 0 else 'openjdk-21-jdk-headless' }}" + name: java-21-openjdk-headless state: present become: true failed_when: false diff --git a/molecule/quarkus-devmode/converge.yml b/molecule/quarkus_devmode/converge.yml similarity index 100% rename from molecule/quarkus-devmode/converge.yml rename to molecule/quarkus_devmode/converge.yml diff --git a/molecule/quarkus-devmode/molecule.yml b/molecule/quarkus_devmode/molecule.yml similarity index 93% rename from molecule/quarkus-devmode/molecule.yml rename to molecule/quarkus_devmode/molecule.yml index 2da7e01..0ae28b3 100644 --- a/molecule/quarkus-devmode/molecule.yml +++ b/molecule/quarkus_devmode/molecule.yml @@ -1,6 +1,6 @@ --- driver: - name: docker + name: podman platforms: - name: instance image: registry.access.redhat.com/ubi9/ubi-init:latest @@ -31,6 +31,8 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" + PROXY: "${PROXY}" + NO_PROXY: "${NO_PROXY}" verifier: name: ansible scenario: diff --git a/molecule/quarkus-devmode/prepare.yml b/molecule/quarkus_devmode/prepare.yml similarity index 100% rename from molecule/quarkus-devmode/prepare.yml rename to molecule/quarkus_devmode/prepare.yml diff --git a/molecule/quarkus-devmode/roles b/molecule/quarkus_devmode/roles similarity index 100% rename from molecule/quarkus-devmode/roles rename to molecule/quarkus_devmode/roles diff --git a/molecule/quarkus-devmode/verify.yml b/molecule/quarkus_devmode/verify.yml similarity index 100% rename from molecule/quarkus-devmode/verify.yml rename to molecule/quarkus_devmode/verify.yml diff --git a/molecule/quarkus_upgrade/molecule.yml b/molecule/quarkus_upgrade/molecule.yml index 21782e8..b121079 100644 --- a/molecule/quarkus_upgrade/molecule.yml +++ b/molecule/quarkus_upgrade/molecule.yml @@ -4,7 +4,7 @@ dependency: options: requirements-file: molecule/requirements.yml driver: - name: docker + name: podman platforms: - name: instance image: registry.access.redhat.com/ubi9/ubi-init:latest @@ -27,6 +27,10 @@ provisioner: host_vars: localhost: ansible_python_interpreter: "{{ ansible_playbook_python }}" + env: + ANSIBLE_FORCE_COLOR: "true" + PROXY: "${PROXY}" + NO_PROXY: "${NO_PROXY}" verifier: name: ansible scenario: From b569e4e7136a34f2d4014b424f346a7375267065 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 29 May 2025 20:14:04 +0200 Subject: [PATCH 370/376] update remote cache test --- molecule/quarkus_ha_remote/converge.yml | 20 +++++++++++++++++++ molecule/quarkus_ha_remote/molecule.yml | 26 +------------------------ molecule/quarkus_ha_remote/prepare.yml | 2 +- molecule/requirements.yml | 1 + 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/molecule/quarkus_ha_remote/converge.yml b/molecule/quarkus_ha_remote/converge.yml index fa5314f..e31ad72 100644 --- a/molecule/quarkus_ha_remote/converge.yml +++ b/molecule/quarkus_ha_remote/converge.yml @@ -1,4 +1,20 @@ --- +- name: Converge + hosts: infinispan + roles: + - role: middleware_automation.infinispan.infinispan + infinispan_service_name: infinispan + infinispan_supervisor_password: remembertochangeme + infinispan_keycloak_caches: true + infinispan_keycloak_persistence: False + infinispan_jdbc_engine: postgres + infinispan_jdbc_url: jdbc:postgresql://postgres:5432/keycloak + infinispan_jdbc_driver_version: 9.4.1212 + infinispan_jdbc_user: keycloak + infinispan_jdbc_pass: mysecretpass + infinispan_users: + - { name: 'testuser', password: 'test', roles: 'observer' } + - name: Converge hosts: keycloak vars: @@ -25,5 +41,9 @@ keycloak_quarkus_db_user: keycloak keycloak_quarkus_db_pass: mysecretpass keycloak_quarkus_db_url: jdbc:postgresql://postgres:5432/keycloak + keycloak_quarkus_cache_remote_username: supervisor + keycloak_quarkus_cache_remote_password: remembertochangeme + keycloak_quarkus_cache_remote_host: "infinispan1:11222" + keycloak_quarkus_cache_remote_tls_enabled: false roles: - role: keycloak_quarkus diff --git a/molecule/quarkus_ha_remote/molecule.yml b/molecule/quarkus_ha_remote/molecule.yml index 673b021..23d8db6 100644 --- a/molecule/quarkus_ha_remote/molecule.yml +++ b/molecule/quarkus_ha_remote/molecule.yml @@ -2,20 +2,7 @@ driver: name: docker platforms: - - name: instance1 - image: registry.access.redhat.com/ubi9/ubi-init:latest - pre_build_image: true - privileged: true - command: "/usr/sbin/init" - groups: - - keycloak - networks: - - name: rhbk - port_bindings: - - "8080/tcp" - - "8443/tcp" - - "9000/tcp" - - name: instance2 + - name: keycloak1 image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true privileged: true @@ -39,17 +26,6 @@ platforms: - name: rhbk port_bindings: - "11222/tcp" - - name: infinispan2 - image: registry.access.redhat.com/ubi9/ubi-init:latest - pre_build_image: true - privileged: true - command: "/usr/sbin/init" - groups: - - infinispan - networks: - - name: rhbk - port_bindings: - - "11222/tcp" - name: postgres image: ubuntu/postgres:14-22.04_beta pre_build_image: true diff --git a/molecule/quarkus_ha_remote/prepare.yml b/molecule/quarkus_ha_remote/prepare.yml index dff1821..16ae9b9 100644 --- a/molecule/quarkus_ha_remote/prepare.yml +++ b/molecule/quarkus_ha_remote/prepare.yml @@ -1,6 +1,6 @@ --- - name: Prepare - hosts: keycloak + hosts: 'keycloak:infinispan' tasks: - name: "Display hera_home if defined." ansible.builtin.set_fact: diff --git a/molecule/requirements.yml b/molecule/requirements.yml index 5c8bb43..125a922 100644 --- a/molecule/requirements.yml +++ b/molecule/requirements.yml @@ -2,6 +2,7 @@ collections: - name: middleware_automation.common - name: middleware_automation.jbcs + - name: middleware_automation.infinispan - name: community.general - name: ansible.posix - name: community.docker From 18de37706feb6fee2e9102aeca22367f72bdf02c Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 29 May 2025 20:31:57 +0200 Subject: [PATCH 371/376] tune Xmx Xms jvm args --- molecule/default/converge.yml | 1 + molecule/quarkus/converge.yml | 1 + molecule/quarkus_devmode/converge.yml | 2 ++ 3 files changed, 4 insertions(+) diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index de97748..e617b59 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -13,6 +13,7 @@ keycloak_quarkus_proxy_mode: none keycloak_quarkus_offline_install: true keycloak_quarkus_download_path: /tmp/keycloak/ + keycloak_quarkus_java_heap_opts: "-Xms640m -Xmx640m " roles: - role: keycloak_quarkus - role: keycloak_realm diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 1114478..fa2d70f 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -24,6 +24,7 @@ keycloak_quarkus_systemd_wait_for_log: true keycloak_quarkus_restart_health_check: false # would fail because of self-signed cert keycloak_quarkus_version: 26.2.4 + keycloak_quarkus_java_heap_opts: "-Xms1024m -Xmx1024m" keycloak_quarkus_additional_env_vars: - key: KC_FEATURES_DISABLED value: impersonation,kerberos diff --git a/molecule/quarkus_devmode/converge.yml b/molecule/quarkus_devmode/converge.yml index 6c0b14f..a596478 100644 --- a/molecule/quarkus_devmode/converge.yml +++ b/molecule/quarkus_devmode/converge.yml @@ -11,6 +11,8 @@ keycloak_quarkus_start_dev: True keycloak_quarkus_proxy_mode: none keycloak_quarkus_java_home: /opt/openjdk/ + keycloak_quarkus_java_heap_opts: "-Xms640m -Xmx640m" + roles: - role: keycloak_quarkus - role: keycloak_realm From de0ea02272a6bb80e5abf871139a7c0c833507a8 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 29 May 2025 21:03:03 +0200 Subject: [PATCH 372/376] ci: move intermittent test back --- .github/workflows/ci.yml | 6 +++--- molecule/quarkus/molecule.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9509a1..a622526 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,8 +21,8 @@ jobs: fqcn: 'middleware_automation/keycloak' debug_verbosity: "${{ github.event.inputs.debug_verbosity }}" molecule_tests: >- - [ "debian", "quarkus_ha", "quarkus_ha_remote" ] + [ "debian", "quarkus", "quarkus_ha", "quarkus_ha_remote" ] podman_tests_current: >- - [ "default", "quarkus", "quarkus_devmode", "quarkus_upgrade" ] + [ "default", "quarkus_devmode", "quarkus_upgrade" ] podman_tests_next: >- - [ "default", "quarkus", "quarkus_devmode", "quarkus_upgrade" ] + [ "default", "quarkus_devmode", "quarkus_upgrade" ] diff --git a/molecule/quarkus/molecule.yml b/molecule/quarkus/molecule.yml index 1b4c8c5..20ca3bc 100644 --- a/molecule/quarkus/molecule.yml +++ b/molecule/quarkus/molecule.yml @@ -1,6 +1,6 @@ --- driver: - name: podman + name: docker platforms: - name: instance image: registry.access.redhat.com/ubi9/ubi-init:latest From 3de96a6666131d5ba808e3fb8043fed9c1ad39ad Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 29 May 2025 21:37:11 +0200 Subject: [PATCH 373/376] single site remote cache --- molecule/quarkus_ha_remote/converge.yml | 5 ++++ roles/keycloak_quarkus/defaults/main.yml | 38 ++++++++++++++++++++---- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/molecule/quarkus_ha_remote/converge.yml b/molecule/quarkus_ha_remote/converge.yml index e31ad72..8df6679 100644 --- a/molecule/quarkus_ha_remote/converge.yml +++ b/molecule/quarkus_ha_remote/converge.yml @@ -45,5 +45,10 @@ keycloak_quarkus_cache_remote_password: remembertochangeme keycloak_quarkus_cache_remote_host: "infinispan1:11222" keycloak_quarkus_cache_remote_tls_enabled: false + keycloak_quarkus_additional_env_vars: + - key: KC_FEATURES + value: clusterless + - key: KC_FEATURES_DISABLED + value: persistent-user-sessions roles: - role: keycloak_quarkus diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index ee12214..0858def 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -38,14 +38,21 @@ keycloak_quarkus_http_enabled: true keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 keycloak_quarkus_http_management_port: 9000 -keycloak_quarkus_jgroups_ip: "{{ ansible_default_ipv4.address }}" keycloak_quarkus_jgroups_port: 7800 +keycloak_quarkus_jgroups_bind_address: "{{ ansible_default_ipv4.address }}" +keycloak_quarkus_jgroups_external_addr: "{{ keycloak_quarkus_jgroups_bind_address }}" +keycloak_quarkus_jgroups_external_port: "{{ keycloak_quarkus_jgroups_port }}" keycloak_quarkus_java_heap_opts: "-Xms1024m -Xmx2048m" -keycloak_quarkus_java_jvm_opts: "-XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 +keycloak_quarkus_java_jvm_opts: > + -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError -Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC -XX:GCTimeRatio=4 - -XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512" -keycloak_quarkus_java_opts: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}" + -XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512 +keycloak_quarkus_jgroups_opts: > + -Djgroups.bind.address={{ keycloak_quarkus_jgroups_bind_address }} + -Djgroups.external_port={{ keycloak_quarkus_jgroups_external_port }} + -Djgroups.external_addr={{ keycloak_quarkus_jgroups_external_addr }} +keycloak_quarkus_java_opts: "{{ ' '.join(keycloak_quarkus_jgroups_opts, keycloak_quarkus_java_heap_opts, keycloak_quarkus_java_jvm_opts }}" keycloak_quarkus_additional_env_vars: [] ### TLS/HTTPS configuration @@ -86,7 +93,7 @@ keycloak_quarkus_hostname_admin: ### Set the path relative to / for serving resources. The path must start with a / ### (set to `/auth` for retrocompatibility with pre-quarkus releases) keycloak_quarkus_http_relative_path: / - +f # Disables dynamically resolving the hostname from request headers. # Should always be set to true in production, unless proxy verifies the Host header. keycloak_quarkus_hostname_strict: true @@ -110,7 +117,28 @@ keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: true keycloak_quarkus_metrics_enabled: false keycloak_quarkus_health_enabled: true +### caches; must read: https://www.keycloak.org/2024/12/storing-sessions-in-kc26 +### embedded caches +# https://www.keycloak.org/server/caching +keycloak_quarkus_cache_metrics_enabled: false +keycloak_quarkus_cache_embedded_authorization_max_count: +keycloak_quarkus_cache_embedded_client_sessions_max_count: +keycloak_quarkus_cache_embedded_crl_max_count: +keycloak_quarkus_cache_embedded_keys_max_count: +keycloak_quarkus_cache_embedded_offline_client_sessions_max_count: +keycloak_quarkus_cache_embedded_offline_sessions_max_count: +keycloak_quarkus_cache_embedded_realms_max_count: +keycloak_quarkus_cache_embedded_sessions_max_count: +keycloak_quarkus_cache_embedded_users_max_count: +keycloak_quarkus_cache_embedded_mtls_enabled: true +keycloak_quarkus_cache_embedded_mtls_key_store_file: "{{ keycloak.home }}/conf/cache_key_store.p12" +keycloak_quarkus_cache_embedded_mtls_key_store_password: '' +keycloak_quarkus_cache_embedded_mtls_rotation_interval_days: 30 +keycloak_quarkus_cache_embedded_mtls_trust_store_file: "{{ keycloak.home }}/conf/cache_trust_store.p12" +keycloak_quarkus_cache_embedded_mtls_trust_store_password: '' + ### infinispan remote caches access (hotrod) +# https://www.keycloak.org/server/caching#_remote_cache keycloak_quarkus_cache_remote_username: supervisor keycloak_quarkus_cache_remote_password: supervisor keycloak_quarkus_cache_remote_host: "localhost:11222" From 3d4bd734f192d62235fc174a170af802a5c51f9e Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 29 May 2025 21:56:50 +0200 Subject: [PATCH 374/376] document new parameters --- roles/keycloak_quarkus/defaults/main.yml | 4 +- .../keycloak_quarkus/meta/argument_specs.yml | 94 +++++++++++++++++-- 2 files changed, 87 insertions(+), 11 deletions(-) diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 0858def..84920a8 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -52,7 +52,7 @@ keycloak_quarkus_jgroups_opts: > -Djgroups.bind.address={{ keycloak_quarkus_jgroups_bind_address }} -Djgroups.external_port={{ keycloak_quarkus_jgroups_external_port }} -Djgroups.external_addr={{ keycloak_quarkus_jgroups_external_addr }} -keycloak_quarkus_java_opts: "{{ ' '.join(keycloak_quarkus_jgroups_opts, keycloak_quarkus_java_heap_opts, keycloak_quarkus_java_jvm_opts }}" +keycloak_quarkus_java_opts: "{{ ' '.join((keycloak_quarkus_jgroups_opts, keycloak_quarkus_java_heap_opts, keycloak_quarkus_java_jvm_opts)) }}" keycloak_quarkus_additional_env_vars: [] ### TLS/HTTPS configuration @@ -93,7 +93,7 @@ keycloak_quarkus_hostname_admin: ### Set the path relative to / for serving resources. The path must start with a / ### (set to `/auth` for retrocompatibility with pre-quarkus releases) keycloak_quarkus_http_relative_path: / -f + # Disables dynamically resolving the hostname from request headers. # Should always be set to true in production, unless proxy verifies the Host header. keycloak_quarkus_hostname_strict: true diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 95d42f4..edd2a07 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -195,14 +195,6 @@ argument_specs: default: 9000 description: "Port of the management interface. Relevant only when something is exposed on the management interface - see the guide for details." type: "int" - keycloak_quarkus_jgroups_ip: - default: "{{ ansible_default_ipv4.address }}" - description: Host jgroups IP. If changing this variable you must make sure it is always set for all hosts in your cluster. - type: "str" - keycloak_quarkus_jgroups_port: - default: 7800 - description: "jgroups cluster tcp port" - type: "int" keycloak_quarkus_java_heap_opts: default: "-Xms1024m -Xmx2048m" description: "Heap memory JVM setting" @@ -215,7 +207,7 @@ argument_specs: description: "Other JVM settings" type: "str" keycloak_quarkus_java_opts: - default: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}" + default: "{{ ' '.join((keycloak_quarkus_jgroups_opts, keycloak_quarkus_java_heap_opts, keycloak_quarkus_java_jvm_opts)) }}" description: "JVM arguments, by default heap_opts + jvm_opts, if overriden it takes precedence over them" type: "str" keycloak_quarkus_additional_env_vars: @@ -472,6 +464,90 @@ argument_specs: description: "Path local to controller for offline/download of install archives" default: "{{ lookup('env', 'PWD') }}" type: "str" + keycloak_quarkus_cache_metrics_enabled: + description: 'Enable histograms for metrics for the embedded caches' + default: false + type: 'bool' + keycloak_quarkus_cache_embedded_authorization_max_count: + description: 'The maximum number of entries that can be stored in-memory by the authorization cache' + required: false + type: "int" + keycloak_quarkus_cache_embedded_client_sessions_max_count: + description: 'The maximum number of entries that can be stored in-memory by the clientSessions cache' + required: false + type: "int" + keycloak_quarkus_cache_embedded_crl_max_count: + description: 'The maximum number of entries that can be stored in-memory by the crl cache' + required: false + type: "int" + keycloak_quarkus_cache_embedded_keys_max_count: + description: 'The maximum number of entries that can be stored in-memory by the keys cache' + required: false + type: "int" + keycloak_quarkus_cache_embedded_offline_client_sessions_max_count: + description: 'The maximum number of entries that can be stored in-memory by the offlineClientSessions cache' + required: false + type: "int" + keycloak_quarkus_cache_embedded_offline_sessions_max_count: + description: 'The maximum number of entries that can be stored in-memory by the offlineSessions cache' + required: false + type: "int" + keycloak_quarkus_cache_embedded_realms_max_count: + description: 'The maximum number of entries that can be stored in-memory by the realms cache' + required: false + type: "int" + keycloak_quarkus_cache_embedded_sessions_max_count: + description: 'The maximum number of entries that can be stored in-memory by the sessions cache' + required: false + type: "int" + keycloak_quarkus_cache_embedded_users_max_count: + description: 'The maximum number of entries that can be stored in-memory by the users cache' + required: false + type: 'int' + keycloak_quarkus_cache_embedded_mtls_enabled: + description: 'Encrypts the network communication between Keycloak servers' + default: true + type: 'bool' + keycloak_quarkus_cache_embedded_mtls_key_store_file: + description: 'The Keystore file path' + default: "{{ keycloak.home }}/conf/cache_key_store.p12" + type: "str" + keycloak_quarkus_cache_embedded_mtls_key_store_password: + description: 'The password to access the Keystore' + default: '' + type: "str" + keycloak_quarkus_cache_embedded_mtls_rotation_interval_days: + description: 'Rotation period in days of automatic JGroups MTLS certificates' + default: 30 + type: 'int' + keycloak_quarkus_cache_embedded_mtls_trust_store_file: + description: 'The Truststore file path' + default: "{{ keycloak.home }}/conf/cache_trust_store.p12" + type: "str" + keycloak_quarkus_cache_embedded_mtls_trust_store_password: + description: 'The password to access the Truststore.' + default: '' + type: "str" + keycloak_quarkus_jgroups_port: + description: 'jgroups bind port' + default: 7800 + type: "int" + keycloak_quarkus_jgroups_bind_address: + description: 'jgroups bind address' + default: "{{ ansible_default_ipv4.address }}" + type: "str" + keycloak_quarkus_jgroups_external_addr: + description: 'IP address that other instances in the Keycloak should use to contact this node' + default: "{{ keycloak_quarkus_jgroups_bind_address }}" + type: "str" + keycloak_quarkus_jgroups_external_port: + description: 'Port that other instances in the Keycloak cluster should use to contact this node' + default: "{{ keycloak_quarkus_jgroups_port }}" + type: "int" + keycloak_quarkus_jgroups_opts: + description: "JVM arguments for jgroups configuration" + default: "-Djgroups.bind.address={{ keycloak_quarkus_jgroups_bind_address }} -Djgroups.external_port={{ keycloak_quarkus_jgroups_external_port }} -Djgroups.external_addr={{ keycloak_quarkus_jgroups_external_addr }}" + type: "str" downstream: options: rhbk_version: From 5c5e84b63e48d3074f58c70af5a62a63642df4ba Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Wed, 4 Jun 2025 20:53:28 +0200 Subject: [PATCH 375/376] Use jdk21 as default in debian --- molecule/debian/molecule.yml | 2 +- molecule/debian/prepare.yml | 8 +------- roles/keycloak_quarkus/vars/debian.yml | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/molecule/debian/molecule.yml b/molecule/debian/molecule.yml index afe29c5..8cccc25 100644 --- a/molecule/debian/molecule.yml +++ b/molecule/debian/molecule.yml @@ -3,7 +3,7 @@ driver: name: docker platforms: - name: instance - image: ghcr.io/hspaans/molecule-containers:debian-11 + image: ghcr.io/hspaans/molecule-containers:debian-13 pre_build_image: true privileged: true port_bindings: diff --git a/molecule/debian/prepare.yml b/molecule/debian/prepare.yml index ed21958..7cab507 100644 --- a/molecule/debian/prepare.yml +++ b/molecule/debian/prepare.yml @@ -7,11 +7,5 @@ ansible.builtin.apt: name: - sudo - # - openjdk-21-jdk-headless # this is not available in ghcr.io/hspaans/molecule-containers:debian-11 (neither in debian-12) since the images are using outdated package sources - - openjdk-17-jdk-headless - state: present - - name: "Install iproute2" - ansible.builtin.apt: - name: + - openjdk-21-jdk-headless - iproute2 - state: present diff --git a/roles/keycloak_quarkus/vars/debian.yml b/roles/keycloak_quarkus/vars/debian.yml index 0af3443..5391dda 100644 --- a/roles/keycloak_quarkus/vars/debian.yml +++ b/roles/keycloak_quarkus/vars/debian.yml @@ -1,5 +1,5 @@ --- -keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('openjdk-17-jdk-headless') }}" +keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('openjdk-21-jdk-headless') }}" keycloak_quarkus_prereq_package_list: - "{{ keycloak_quarkus_varjvm_package }}" - bash From bcc961999c7c6a94d2ee7a08b190ea23ea4da8b6 Mon Sep 17 00:00:00 2001 From: Guido Grazioli Date: Thu, 5 Jun 2025 12:02:43 +0200 Subject: [PATCH 376/376] implement Single site - Sessions stored in external Infinispan --- molecule/quarkus_ha_remote/converge.yml | 5 ++++- roles/keycloak_quarkus/README.md | 4 +++- roles/keycloak_quarkus/defaults/main.yml | 4 +++- roles/keycloak_quarkus/meta/argument_specs.yml | 12 ++++++++++-- roles/keycloak_quarkus/templates/keycloak.conf.j2 | 8 ++++++-- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/molecule/quarkus_ha_remote/converge.yml b/molecule/quarkus_ha_remote/converge.yml index 8df6679..e62ae23 100644 --- a/molecule/quarkus_ha_remote/converge.yml +++ b/molecule/quarkus_ha_remote/converge.yml @@ -12,6 +12,7 @@ infinispan_jdbc_driver_version: 9.4.1212 infinispan_jdbc_user: keycloak infinispan_jdbc_pass: mysecretpass + infinispan_bind_address: "{{ ansible_default_ipv4.address }}" infinispan_users: - { name: 'testuser', password: 'test', roles: 'observer' } @@ -41,9 +42,11 @@ keycloak_quarkus_db_user: keycloak keycloak_quarkus_db_pass: mysecretpass keycloak_quarkus_db_url: jdbc:postgresql://postgres:5432/keycloak + keycloak_quarkus_cache_remote: true keycloak_quarkus_cache_remote_username: supervisor keycloak_quarkus_cache_remote_password: remembertochangeme - keycloak_quarkus_cache_remote_host: "infinispan1:11222" + keycloak_quarkus_cache_remote_host: "infinispan1" + keycloak_quarkus_cache_remote_port: 11222 keycloak_quarkus_cache_remote_tls_enabled: false keycloak_quarkus_additional_env_vars: - key: KC_FEATURES diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 0da7272..c461203 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -147,9 +147,11 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| +|`keycloak_quarkus_cache_remote` | Whether to connect to remote cache infinispan server | `false` | |`keycloak_quarkus_cache_remote_username` | Username for connecting to infinispan | `supervisor` | |`keycloak_quarkus_cache_remote_password` | Password for connecting to infinispan | `supervisor` | -|`keycloak_quarkus_cache_remote_host` | host name/port for connecting to infinispan, eg. host1:11222;host2:11222 | `localhost:11222` | +|`keycloak_quarkus_cache_remote_host` | Hostname for connecting to infinispan | `localhost` | +|`keycloak_quarkus_cache_remote_port`| Port for connecting to infinispan | `11222` | |`keycloak_quarkus_cache_remote_sasl_mechanism` | Infinispan auth mechanism | `SCRAM-SHA-512` | |`keycloak_quarkus_cache_remote_tls_enabled` | Whether infinispan uses TLS connection | `false` | diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 84920a8..d53c790 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -139,9 +139,11 @@ keycloak_quarkus_cache_embedded_mtls_trust_store_password: '' ### infinispan remote caches access (hotrod) # https://www.keycloak.org/server/caching#_remote_cache +keycloak_quarkus_cache_remote: false keycloak_quarkus_cache_remote_username: supervisor keycloak_quarkus_cache_remote_password: supervisor -keycloak_quarkus_cache_remote_host: "localhost:11222" +keycloak_quarkus_cache_remote_host: localhost +keycloak_quarkus_cache_remote_port: 11222 keycloak_quarkus_cache_remote_tls_enabled: false keycloak_quarkus_cache_remote_sasl_mechanism: SCRAM-SHA-512 diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index edd2a07..1683321 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -255,6 +255,10 @@ argument_specs: default: true description: "If the server should expose health check endpoints on the management interface" type: "bool" + keycloak_quarkus_cache_remote: + description: "Whether to connect to remote cache infinispan server" + default: false + type: 'bool' keycloak_quarkus_cache_remote_username: default: "supervisor" description: "Username for connecting to infinispan" @@ -264,8 +268,12 @@ argument_specs: description: "Password for connecting to infinispan" type: "str" keycloak_quarkus_cache_remote_host: - default: "localhost:11222" - description: "host name/port for connecting to infinispan, eg. host1:11222;host2:11222" + default: "localhost" + description: "Hostname for connecting to infinispan" + type: "str" + keycloak_quarkus_cache_remote_port: + default: "11222" + description: "Port for connecting to infinispan" type: "str" keycloak_quarkus_cache_remote_sasl_mechanism: default: "SCRAM-SHA-512" diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index 99790c3..7642715 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -59,8 +59,12 @@ hostname-backchannel-dynamic={{ keycloak_quarkus_hostname_backchannel_dynamic | {% if keycloak_quarkus_ha_enabled %} cache=ispn cache-config-file=cache-ispn.xml -{% if keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING' %} -# cache-stack=tcp # configured directly in `cache-ispn.xml` +{% if keycloak_quarkus_cache_remote %} +cache-remote-username={{ keycloak_quarkus_cache_remote_username }} +cache-remote-password={{ keycloak_quarkus_cache_remote_password }} +cache-remote-host={{ keycloak_quarkus_cache_remote_host }} +cache-remote-port={{ keycloak_quarkus_cache_remote_port }} +cache-remote-tls-enabled={{ keycloak_quarkus_cache_remote_tls_enabled | lower }} {% endif %} {% endif %}