Compare commits

...

33 Commits
1.2.1 ... 1.2.5

Author SHA1 Message Date
github-actions
b7eef6a720 Update changelog for release 1.2.5 2023-05-26 21:00:15 +00:00
Guido Grazioli
203e6c06ac Merge pull request #86 from guidograzioli/admin_url
Allow to configure administration endpoint URL
2023-05-26 19:46:59 +02:00
Guido Grazioli
aaae1d1129 Allow to configure admin_url 2023-05-26 16:31:13 +02:00
Guido Grazioli
cca20a067d Merge pull request #85 from guidograzioli/datasource_validation
Add configuration for database connection pool validation
2023-05-26 16:09:51 +02:00
Guido Grazioli
2be35f9a67 typo in readme 2023-05-26 14:28:52 +02:00
Guido Grazioli
19f1750a33 Add db pool validation configuration 2023-05-25 11:47:19 +02:00
Guido Grazioli
c3d8bbc94e Merge pull request #84 from guidograzioli/hostname_spi
Allow to force backend URLs to frontend URLs
2023-05-25 11:34:37 +02:00
Guido Grazioli
c4b4be3c3b add variable for force_frontend_url 2023-05-25 11:10:18 +02:00
Guido Grazioli
98e1633c43 ci: new linter rules take 2 2023-05-22 16:24:28 +02:00
Guido Grazioli
fd375a141d ci: update linter settings, fix new linter issues 2023-05-22 16:12:25 +02:00
Guido Grazioli
0cf7b3ac49 Merge pull request #81 from world-direct/fix/80
Close #80 - introduce systemd restart behavior
2023-05-22 15:41:30 +02:00
Helmut Wolf
370d424b24 Close #80 - introduce systemd restart behavior 2023-05-22 11:30:11 +02:00
Guido Grazioli
01fd2cc4fd Bump to 1.2.5 2023-05-09 16:44:16 +02:00
github-actions
7471e07921 Update changelog for release 1.2.4 2023-05-09 13:49:15 +00:00
Guido Grazioli
e8e0f6718b Merge pull request #78 from world-direct/fix/74
Close #74 - add `sqlserver` support to keycloak role
2023-05-09 15:31:01 +02:00
Guido Grazioli
e4811221be ci: fix release wf, bump to 1.2.4 2023-05-09 15:25:41 +02:00
Guido Grazioli
6cb4aac556 Merge pull request #77 from world-direct/fix/76
Close #76 - Keycloak role: fix deprecation warning for `ipaddr`
2023-05-09 15:14:07 +02:00
Helmut Wolf
aad373a8e9 Close #74 - add sqlserver support to keycloak role 2023-05-09 13:14:42 +02:00
Helmut Wolf
fd0a4e4492 Close #76 - Keycloak role: fix deprecation warning for ipaddr 2023-05-09 11:45:25 +02:00
Guido Grazioli
706677910b ci: update apt before installing hub 2023-05-05 11:07:42 +02:00
Guido Grazioli
a3bffe9401 Bump to 1.2.3 2023-05-03 15:23:46 +02:00
Guido Grazioli
f566917bc2 ci: rename galaxy tag 2023-05-03 08:54:20 +02:00
Guido Grazioli
44ad3b8e6d add galaxy tag 2023-05-02 18:05:12 +02:00
Guido Grazioli
1a450ea1d7 ci: add galaxy tags 2023-05-02 17:00:26 +02:00
Guido Grazioli
b0a01a8e46 Merge pull request #73 from jonathanspw/main
add configurability for XA transactions
2023-04-24 16:48:20 +02:00
Jonathan Wright
020bc86955 document keycloak_quarkus_transaction_xa_enabled 2023-04-24 08:52:36 -05:00
Jonathan Wright
d72d46c945 fix typo 2023-04-24 08:50:16 -05:00
Jonathan Wright
c7d2bdcee3 add configurability for XA transactions 2023-04-21 15:12:59 -05:00
Guido Grazioli
43d978370d bump to 1.2.2 2023-04-14 15:50:48 +02:00
Guido Grazioli
3d37def38d Merge pull request #71 from guidograzioli/downstream_offline_patching_fix
Fix undefined facts when offline patching sso
2023-04-14 15:31:13 +02:00
Guido Grazioli
8d16e241c1 fix undefined facts when offline patching sso 2023-04-14 14:58:40 +02:00
Guido Grazioli
6ac0c18842 fix: drop xml element not available in 7.6 2023-04-12 11:12:32 +02:00
Guido Grazioli
6334daf244 ci: fix typo and indent for TCPPING discovery 2023-04-12 10:59:21 +02:00
30 changed files with 302 additions and 146 deletions

View File

@@ -21,19 +21,21 @@ 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]
- blocked_modules
skip_list:
- vars_should_not_be_used
- file_is_small_enough
- name[template]
use_default_rules: true
parseable: true

View File

@@ -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: |

View File

@@ -32,15 +32,17 @@ 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: |
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

View File

@@ -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
@@ -47,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

2
.gitignore vendored
View File

@@ -2,6 +2,8 @@
*.zip
.tmp
.cache
.vscode/
__pycache__/
docs/plugins/
docs/roles/
docs/_build/

View File

@@ -6,6 +6,32 @@ 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 <https://github.com/ansible-middleware/keycloak/pull/85>`_
- Allow to configure administration endpoint URL `#86 <https://github.com/ansible-middleware/keycloak/pull/86>`_
- Allow to force backend URLs to frontend URLs `#84 <https://github.com/ansible-middleware/keycloak/pull/84>`_
- Introduce systemd unit restart behavior `#81 <https://github.com/ansible-middleware/keycloak/pull/81>`_
v1.2.4
======
Minor Changes
-------------
- Add ``sqlserver`` to keycloak role jdbc configurations `#78 <https://github.com/ansible-middleware/keycloak/pull/78>`_
- Add configurability for XA transactions `#73 <https://github.com/ansible-middleware/keycloak/pull/73>`_
Bugfixes
--------
- Fix deprecation warning for ``ipaddr`` `#77 <https://github.com/ansible-middleware/keycloak/pull/77>`_
- Fix undefined facts when offline patching sso `#71 <https://github.com/ansible-middleware/keycloak/pull/71>`_
v1.2.1
======

View File

@@ -181,3 +181,46 @@ releases:
- 68.yaml
- 69.yaml
release_date: '2023-04-11'
1.2.4:
changes:
bugfixes:
- 'Fix deprecation warning for ``ipaddr`` `#77 <https://github.com/ansible-middleware/keycloak/pull/77>`_
'
- 'Fix undefined facts when offline patching sso `#71 <https://github.com/ansible-middleware/keycloak/pull/71>`_
'
minor_changes:
- 'Add ``sqlserver`` to keycloak role jdbc configurations `#78 <https://github.com/ansible-middleware/keycloak/pull/78>`_
'
- 'Add configurability for XA transactions `#73 <https://github.com/ansible-middleware/keycloak/pull/73>`_
'
fragments:
- 71.yaml
- 73.yaml
- 77.yaml
- 78.yaml
release_date: '2023-05-09'
1.2.5:
changes:
minor_changes:
- 'Add configuration for database connection pool validation `#85 <https://github.com/ansible-middleware/keycloak/pull/85>`_
'
- 'Allow to configure administration endpoint URL `#86 <https://github.com/ansible-middleware/keycloak/pull/86>`_
'
- 'Allow to force backend URLs to frontend URLs `#84 <https://github.com/ansible-middleware/keycloak/pull/84>`_
'
- 'Introduce systemd unit restart behavior `#81 <https://github.com/ansible-middleware/keycloak/pull/81>`_
'
fragments:
- 81.yaml
- 84.yaml
- 85.yaml
- 86.yaml
release_date: '2023-05-26'

View File

@@ -1,7 +1,7 @@
---
namespace: middleware_automation
name: keycloak
version: "1.2.1"
version: "1.2.5"
readme: README.md
authors:
- Romain Pelisse <rpelisse@redhat.com>
@@ -21,8 +21,11 @@ tags:
- infrastructure
- authentication
- java
- runtimes
- 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

View File

@@ -14,9 +14,12 @@
that:
- ansible_facts.services["keycloak.service"]["state"] == "running"
- ansible_facts.services["keycloak.service"]["status"] == "enabled"
- name: Verify we are running on requested jvm
shell: |
- 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
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:

View File

@@ -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

View File

@@ -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 blocked_modules 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'

View File

@@ -1,52 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2021 Eric Lavarde <elavarde@redhat.com>
# 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
}

View File

@@ -1,22 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Felix Fontein <felix@fontein.de>
# 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)

View File

@@ -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` |
@@ -83,7 +87,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/<version>/<archive>`|
|`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/<version>/<archive>`|
|`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 }}` |
@@ -106,6 +110,12 @@ 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` |
|`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
@@ -116,10 +126,10 @@ 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:
The following parameters are _required_ only when `keycloak_ha_enabled` is True:
| Variable | Description | Default |
|:---------|:------------|:--------|
@@ -127,7 +137,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` |
@@ -137,7 +147,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 |
|:---------|:------------|:---------|
@@ -147,6 +157,14 @@ 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 |
|`keycloak_admin_url` | Override the default administration endpoint URL |
Example Playbook
-----------------
@@ -157,8 +175,6 @@ Example Playbook
- hosts: ...
vars:
keycloak_admin_password: "remembertochangeme"
collections:
- middleware_automation.keycloak
roles:
- middleware_automation.keycloak.keycloak
```

View File

@@ -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,9 @@ keycloak_modcluster_urls:
port: "{{ keycloak_modcluster_port }}"
### keycloak frontend url
keycloak_frontend_url: http://localhost:8080/auth
keycloak_frontend_url: http://localhost:8080/auth/
keycloak_frontend_url_force: False
keycloak_admin_url:
### infinispan remote caches access (hotrod)
keycloak_infinispan_user: supervisor
@@ -79,11 +85,17 @@ 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
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
@@ -94,5 +106,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

View File

@@ -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"
@@ -237,7 +241,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
@@ -290,6 +294,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"
@@ -298,6 +318,26 @@ 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"
keycloak_admin_url:
required: False
description: "Override the default administration endpoint URL"
type: "str"
downstream:
options:
sso_version:

View File

@@ -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 }}"
@@ -266,5 +266,5 @@
- restart keycloak
when:
- keycloak_ha_enabled
- keycloak_remote_cache_enabled
- keycloak_remote_cache_enabled
- keycloak_config_override_template | length == 0

View File

@@ -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:
@@ -35,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

View File

@@ -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
@@ -32,15 +35,15 @@
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:
sso_latest_version: "{{ filtered_versions | middleware_automation.keycloak.version_sort | last }}"
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
@@ -55,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 }}"

View File

@@ -631,7 +631,7 @@
</mail-session>
</subsystem>
<subsystem xmlns="urn:wildfly:metrics:1.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:jboss}"/>
{% if keycloak_modcluster.enabled %}
{% if keycloak_modcluster.enabled %}
<subsystem xmlns="urn:jboss:domain:modcluster:5.0">
<proxy name="default" advertise="false" listener="ajp" proxies="proxy1">
<dynamic-load-provider>
@@ -639,7 +639,7 @@
</dynamic-load-provider>
</proxy>
</subsystem>
{% endif %}
{% endif %}
<subsystem xmlns="urn:jboss:domain:naming:2.0">
<remote-naming/>
</subsystem>
@@ -728,7 +728,7 @@
</interface>
<interface name="jgroups">
{% if ansible_default_ipv4 is defined %}
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ipaddr('net') }}"/>
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') }}"/>
{% else %}
<any-address />
{% endif %}

View File

@@ -725,7 +725,7 @@
</interface>
<interface name="jgroups">
{% if ansible_default_ipv4 is defined %}
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ipaddr('net') }}"/>
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') }}"/>
{% else %}
<any-address />
{% endif %}

View File

@@ -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

View File

@@ -136,6 +136,12 @@
<user-name>{{ keycloak_jdbc[keycloak_jdbc_engine].db_user }}</user-name>
<password>{{ keycloak_jdbc[keycloak_jdbc_engine].db_password }}</password>
</security>
<validation>
<check-valid-connection-sql>{{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }}</check-valid-connection-sql>
<validate-on-match>{{ keycloak_db_background_validate_on_match }}</validate-on-match>
<background-validation>{{ keycloak_db_background_validation }}</background-validation>
<background-validation-millis>{{ keycloak_db_background_validation_millis }}</background-validation-millis>
</validation>
{% else %}
<connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
<driver>h2</driver>
@@ -376,7 +382,6 @@
<distributed-cache name="offlineClientSessions" owners="2"/>
<distributed-cache name="loginFailures" owners="2"/>
<distributed-cache name="actionTokens" owners="2">
<object-memory size="-1"/>
<expiration interval="300000" max-idle="-1"/>
</distributed-cache>
<local-cache name="authorization">
@@ -574,7 +579,10 @@
<provider name="default" enabled="true">
<properties>
<property name="frontendUrl" value="{{ keycloak_modcluster.frontend_url }}"/>
<property name="forceBackendUrlToFrontendUrl" value="true"/>
<property name="forceBackendUrlToFrontendUrl" value="{{ keycloak_modcluster.force_frontend_url }}"/>
{% if keycloak_modcluster.admin_url | length > 0 %}
<property name="adminUrl" value="{{ keycloak_modcluster.admin_url }}" />
{% endif %}
</properties>
</provider>
</spi>
@@ -585,7 +593,7 @@
</mail-session>
</subsystem>
<subsystem xmlns="urn:wildfly:metrics:1.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:jboss}"/>
{% if keycloak_modcluster.enabled %}
{% if keycloak_modcluster.enabled %}
<subsystem xmlns="urn:jboss:domain:modcluster:5.0">
<proxy name="default" advertise="false" listener="ajp" proxies="{{ ['proxy_'] | product(keycloak_modcluster.reverse_proxy_urls | map(attribute='host')) | map('join') | list | join(' ') }}">
<dynamic-load-provider>
@@ -593,7 +601,7 @@
</dynamic-load-provider>
</proxy>
</subsystem>
{% endif %}
{% endif %}
<subsystem xmlns="urn:jboss:domain:naming:2.0">
<remote-naming/>
</subsystem>
@@ -639,7 +647,7 @@
</handlers>
<application-security-domains>
<application-security-domain name="other" security-domain="ApplicationDomain"/>
</application-security-domains>
</application-security-domains>
<filters>
<filter name="proxy-peer" module="io.undertow.core"
class-name="io.undertow.server.handlers.ProxyPeerAddressHandler"/>
@@ -653,7 +661,7 @@
</interface>
<interface name="jgroups">
{% if ansible_default_ipv4 is defined %}
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ipaddr('net') }}"/>
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') }}"/>
{% else %}
<any-address />
{% endif %}

View File

@@ -136,6 +136,12 @@
<user-name>{{ keycloak_jdbc[keycloak_jdbc_engine].db_user }}</user-name>
<password>{{ keycloak_jdbc[keycloak_jdbc_engine].db_password }}</password>
</security>
<validation>
<check-valid-connection-sql>{{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }}</check-valid-connection-sql>
<validate-on-match>{{ keycloak_db_background_validate_on_match }}</validate-on-match>
<background-validation>{{ keycloak_db_background_validation }}</background-validation>
<background-validation-millis>{{ keycloak_db_background_validation_millis }}</background-validation-millis>
</validation>
{% else %}
<connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
<driver>h2</driver>
@@ -611,7 +617,10 @@
<provider name="default" enabled="true">
<properties>
<property name="frontendUrl" value="{{ keycloak_modcluster.frontend_url }}"/>
<property name="forceBackendUrlToFrontendUrl" value="true"/>
<property name="forceBackendUrlToFrontendUrl" value="{{ keycloak_modcluster.force_frontend_url }}"/>
{% if keycloak_modcluster.admin_url | length > 0 %}
<property name="adminUrl" value="{{ keycloak_modcluster.admin_url }}" />
{% endif %}
</properties>
</provider>
</spi>
@@ -622,7 +631,7 @@
</mail-session>
</subsystem>
<subsystem xmlns="urn:wildfly:metrics:1.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:jboss}"/>
{% if keycloak_modcluster.enabled %}
{% if keycloak_modcluster.enabled %}
<subsystem xmlns="urn:jboss:domain:modcluster:5.0">
<proxy name="default" advertise="false" listener="ajp" proxies="{{ ['proxy_'] | product(keycloak_modcluster.reverse_proxy_urls | map(attribute='host')) | map('join') | list | join(' ') }}">
<dynamic-load-provider>
@@ -630,7 +639,7 @@
</dynamic-load-provider>
</proxy>
</subsystem>
{% endif %}
{% endif %}
<subsystem xmlns="urn:jboss:domain:naming:2.0">
<remote-naming/>
</subsystem>
@@ -676,7 +685,7 @@
</handlers>
<application-security-domains>
<application-security-domain name="other" security-domain="ApplicationDomain"/>
</application-security-domains>
</application-security-domains>
<filters>
<filter name="proxy-peer" module="io.undertow.core"
class-name="io.undertow.server.handlers.ProxyPeerAddressHandler"/>
@@ -690,7 +699,7 @@
</interface>
<interface name="jgroups">
{% if ansible_default_ipv4 is defined %}
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ipaddr('net') }}"/>
<subnet-match value="{{ (ansible_default_ipv4.network + '/' + ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') }}"/>
{% else %}
<any-address />
{% endif %}

View File

@@ -123,6 +123,12 @@
<user-name>{{ keycloak_jdbc[keycloak_jdbc_engine].db_user }}</user-name>
<password>{{ keycloak_jdbc[keycloak_jdbc_engine].db_password }}</password>
</security>
<validation>
<check-valid-connection-sql>{{ keycloak_jdbc[keycloak_jdbc_engine].validate_query }}</check-valid-connection-sql>
<validate-on-match>{{ keycloak_db_background_validate_on_match }}</validate-on-match>
<background-validation>{{ keycloak_db_background_validation }}</background-validation>
<background-validation-millis>{{ keycloak_db_background_validation_millis }}</background-validation-millis>
</validation>
{% else %}
<connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
<driver>h2</driver>
@@ -517,7 +523,10 @@
<provider name="default" enabled="true">
<properties>
<property name="frontendUrl" value="{{ keycloak_modcluster.frontend_url }}"/>
<property name="forceBackendUrlToFrontendUrl" value="true"/>
<property name="forceBackendUrlToFrontendUrl" value="{{ keycloak_modcluster.force_frontend_url }}"/>
{% if keycloak_modcluster.admin_url | length > 0 %}
<property name="adminUrl" value="{{ keycloak_modcluster.admin_url }}" />
{% endif %}
</properties>
</provider>
</spi>

View File

@@ -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,
@@ -56,12 +58,37 @@ 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 }}"
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
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:
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 }}"
admin_url: "{{ keycloak_admin_url | default('') }}"
# infinispan
keycloak_remotecache:

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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 }}