Skip to content

Commit

Permalink
Add restart strategies, and allow custom task include
Browse files Browse the repository at this point in the history
Co-authored-by: Helmut Wolf <[email protected]>
Co-authored-by: Guido Grazioli <[email protected]>
  • Loading branch information
guidograzioli and Helmut Wolf committed May 15, 2024
1 parent 1e9a669 commit 2d573c2
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 45 deletions.
5 changes: 5 additions & 0 deletions roles/keycloak_quarkus/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 2 additions & 1 deletion roles/keycloak_quarkus/handlers/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
22 changes: 21 additions & 1 deletion roles/keycloak_quarkus/meta/argument_specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions roles/keycloak_quarkus/tasks/install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}"
Expand All @@ -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'
Expand Down
18 changes: 13 additions & 5 deletions roles/keycloak_quarkus/tasks/prereqs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down
51 changes: 15 additions & 36 deletions roles/keycloak_quarkus/tasks/restart.yml
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions roles/keycloak_quarkus/tasks/restart/none.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
- name: "Display message"
ansible.builtin.debug:
msg: "keycloak_quarkus_restart_strategy is none, skipping restart"
8 changes: 8 additions & 0 deletions roles/keycloak_quarkus/tasks/restart/serial.yml
Original file line number Diff line number Diff line change
@@ -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 }}"
34 changes: 34 additions & 0 deletions roles/keycloak_quarkus/tasks/restart/verify_first.yml
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 2d573c2

Please sign in to comment.