mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-09-08 19:27:18 +02:00
Compare commits
9 Commits
14e868a644
...
7d0502ebc5
Author | SHA1 | Date | |
---|---|---|---|
7d0502ebc5 | |||
20c8d46f54 | |||
a524c52f89 | |||
5c9ca20e04 | |||
bfe18dd83c | |||
0a83f3159a | |||
fb7b3a3c8e | |||
42f9ebad34 | |||
33b2d3f582 |
@@ -4,5 +4,5 @@ OnFailure=sys-alm-compose.{{ SOFTWARE_NAME }}@%n.service sys-cln-faild-bkps{{ SY
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStartPre=/bin/sh -c '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ system_maintenance_services | join(' ') }} --ignore {{system_maintenance_backup_services| join(' ') }} --timeout "{{system_maintenance_lock_timeout_backup_services}}"'
|
||||
ExecStartPre=/bin/sh -c '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ system_maintenance_services | join(' ') }} --ignore {{system_maintenance_backup_services| join(' ') }} --timeout "{{ system_maintenance_lock_timeout_backup_services }}"'
|
||||
ExecStart=/bin/sh -c '/usr/bin/bash {{docker_backup_remote_to_local_folder}}sys-bkp-rmt-2-loc-multi-provider.sh'
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
# GENERAL
|
||||
## Admin (Data)
|
||||
LDAP_ADMIN_USERNAME= {{applications | get_app_conf(application_id, 'users.administrator.username', True)}} # LDAP database admin user.
|
||||
LDAP_ADMIN_USERNAME= {{ applications | get_app_conf(application_id, 'users.administrator.username') }} # LDAP database admin user.
|
||||
LDAP_ADMIN_PASSWORD= {{ldap.bind_credential}} # LDAP database admin password.
|
||||
|
||||
## Users
|
||||
@@ -14,8 +14,8 @@ LDAP_ROOT= {{ldap.dn.root}} # LDAP baseDN (or su
|
||||
## Admin (Config)
|
||||
LDAP_ADMIN_DN= {{ldap.dn.administrator.data}}
|
||||
LDAP_CONFIG_ADMIN_ENABLED= yes
|
||||
LDAP_CONFIG_ADMIN_USERNAME= {{applications | get_app_conf(application_id, 'users.administrator.username', True)}}
|
||||
LDAP_CONFIG_ADMIN_PASSWORD= {{applications | get_app_conf(application_id, 'credentials.administrator_password', True)}}
|
||||
LDAP_CONFIG_ADMIN_USERNAME= {{ applications | get_app_conf(application_id, 'users.administrator.username') }}
|
||||
LDAP_CONFIG_ADMIN_PASSWORD= {{ applications | get_app_conf(application_id, 'credentials.administrator_password') }}
|
||||
|
||||
# Network
|
||||
LDAP_PORT_NUMBER= {{openldap_docker_port_open}} # Route to default port
|
||||
|
@@ -1,9 +1,9 @@
|
||||
- name: "reload sys-bkp-docker-2-loc-everything service"
|
||||
- name: "reload backup docker to local (all) service"
|
||||
systemd:
|
||||
name: sys-bkp-docker-2-loc-everything{{ SYS_SERVICE_SUFFIX }}
|
||||
name: "{{ BKP_DOCKER_2_LOC_SERVICE_ALL }}"
|
||||
daemon_reload: yes
|
||||
|
||||
- name: "reload sys-bkp-docker-2-loc service"
|
||||
- name: "reload backup docker to local service"
|
||||
systemd:
|
||||
name: sys-bkp-docker-2-loc{{ SYS_SERVICE_SUFFIX }}
|
||||
name: "{{ BKP_DOCKER_2_LOC_SERVICE }}"
|
||||
daemon_reload: yes
|
@@ -14,17 +14,17 @@
|
||||
include_tasks: 03_reset.yml
|
||||
when: MODE_RESET | bool
|
||||
|
||||
- name: configure sys-bkp-docker-2-loc-everything service
|
||||
- name: "setup '{{ BKP_DOCKER_2_LOC_SERVICE_ALL }}'"
|
||||
template:
|
||||
src: sys-bkp-docker-2-loc-everything.service.j2
|
||||
dest: /etc/systemd/system/sys-bkp-docker-2-loc-everything{{ SYS_SERVICE_SUFFIX }}
|
||||
notify: reload sys-bkp-docker-2-loc-everything service
|
||||
src: "{{ role_name }}-everything.service.j2"
|
||||
dest: /etc/systemd/system/{{ BKP_DOCKER_2_LOC_SERVICE_ALL }}
|
||||
notify: reload backup docker to local (all) service
|
||||
|
||||
- name: configure sys-bkp-docker-2-loc{{ SYS_SERVICE_SUFFIX }}
|
||||
- name: "setup '{{ BKP_DOCKER_2_LOC_SERVICE }}'"
|
||||
template:
|
||||
src: sys-bkp-docker-2-loc.service.j2
|
||||
dest: /etc/systemd/system/sys-bkp-docker-2-loc{{ SYS_SERVICE_SUFFIX }}
|
||||
notify: reload sys-bkp-docker-2-loc service
|
||||
src: "{{ role_name }}.service.j2"
|
||||
dest: /etc/systemd/system/{{ BKP_DOCKER_2_LOC_SERVICE }}
|
||||
notify: reload backup docker to local service
|
||||
|
||||
- name: "set 'service_name' to '{{ role_name }}'"
|
||||
set_fact:
|
||||
|
@@ -1,12 +1,12 @@
|
||||
- block:
|
||||
- name: "pkgmgr install {{ bkp_docker_2_loc_pkg }}"
|
||||
- name: "pkgmgr install {{ BKP_DOCKER_2_LOC_PKG }}"
|
||||
include_role:
|
||||
name: pkgmgr-install
|
||||
vars:
|
||||
package_name: "{{ bkp_docker_2_loc_pkg }}"
|
||||
package_name: "{{ BKP_DOCKER_2_LOC_PKG }}"
|
||||
|
||||
- name: "Retrieve {{ bkp_docker_2_loc_pkg }} path from pkgmgr"
|
||||
command: "pkgmgr path {{ bkp_docker_2_loc_pkg }}"
|
||||
- name: "Retrieve {{ BKP_DOCKER_2_LOC_PKG }} path from pkgmgr"
|
||||
command: "pkgmgr path {{ BKP_DOCKER_2_LOC_PKG }}"
|
||||
register: pkgmgr_output
|
||||
changed_when: false
|
||||
|
||||
@@ -16,4 +16,4 @@
|
||||
changed_when: false
|
||||
when: backup_docker_to_local_folder is not defined
|
||||
vars:
|
||||
bkp_docker_2_loc_pkg: backup-docker-to-local
|
||||
BKP_DOCKER_2_LOC_PKG: backup-docker-to-local
|
||||
|
@@ -55,10 +55,10 @@
|
||||
database_name is defined and
|
||||
database_username is defined and
|
||||
database_password is defined) and
|
||||
run_once_bkp_docker_2_loc_file_permission is not defined
|
||||
run_once_sys_bkp_docker_2_loc_file_permission is not defined
|
||||
register: file_permission_result
|
||||
|
||||
- name: run the backup_docker_to_local_file_permission tasks once
|
||||
set_fact:
|
||||
run_once_bkp_docker_2_loc_file_permission: true
|
||||
when: run_once_bkp_docker_2_loc_file_permission is not defined and file_permission_result is defined and file_permission_result.changed
|
||||
run_once_sys_bkp_docker_2_loc_file_permission: true
|
||||
when: run_once_sys_bkp_docker_2_loc_file_permission is not defined and file_permission_result is defined and file_permission_result.changed
|
@@ -7,4 +7,4 @@
|
||||
- name: "include 04_seed-database-to-backup.yml"
|
||||
include_tasks: 04_seed-database-to-backup.yml
|
||||
when:
|
||||
- bkp_docker_2_loc_db_enabled | bool
|
||||
- BKP_DOCKER_2_LOC_DB_ENABLED | bool
|
||||
|
@@ -4,6 +4,6 @@ OnFailure=sys-alm-compose.{{ SOFTWARE_NAME }}@%n.service sys-cln-faild-bkps{{ SY
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStartPre=/bin/sh -c '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ system_maintenance_services | join(' ') }} --ignore {{ system_maintenance_backup_services | reject('equalto', 'sys-bkp-docker-2-loc') | join(' ') }} --timeout "{{system_maintenance_lock_timeout_backup_services}}"'
|
||||
ExecStart=/bin/sh -c '{{ bkp_docker_2_loc_exec }} --everything'
|
||||
ExecStartPre=/bin/sh -c '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ system_maintenance_services | join(' ') }} --ignore {{ system_maintenance_backup_services | reject('equalto', role_name ) | join(' ') }} --timeout "{{ system_maintenance_lock_timeout_backup_services }}"'
|
||||
ExecStart=/bin/sh -c '{{ BKP_DOCKER_2_LOC_EXEC }} --everything'
|
||||
ExecStartPost=/bin/sh -c '/bin/systemctl start sys-rpr-docker-soft{{ SYS_SERVICE_SUFFIX }} &'
|
@@ -4,6 +4,6 @@ OnFailure=sys-alm-compose.{{ SOFTWARE_NAME }}@%n.service sys-cln-faild-bkps{{ SY
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStartPre=/bin/sh -c '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ system_maintenance_services | join(' ') }} --ignore {{ system_maintenance_backup_services | reject('equalto', 'sys-bkp-docker-2-loc-everything') | join(' ') }} --timeout "{{system_maintenance_lock_timeout_backup_services}}"'
|
||||
ExecStart=/bin/sh -c '{{ bkp_docker_2_loc_exec }}'
|
||||
ExecStartPre=/bin/sh -c '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ system_maintenance_services | join(' ') }} --ignore {{ system_maintenance_backup_services | reject('equalto', role_name ~ '-everything') | join(' ') }} --timeout "{{ system_maintenance_lock_timeout_backup_services }}"'
|
||||
ExecStart=/bin/sh -c '{{ BKP_DOCKER_2_LOC_EXEC }}'
|
||||
ExecStartPost=/bin/sh -c '/bin/systemctl start sys-rpr-docker-soft{{ SYS_SERVICE_SUFFIX }} &'
|
@@ -1,46 +1,50 @@
|
||||
# Mapping logic for backup-docker-to-local CLI arguments
|
||||
#
|
||||
# - bkp_docker_2_loc_database_routine: All service names where backup.database_routine is set (for --database-containers)
|
||||
# - bkp_docker_2_loc_no_stop_required: All images where backup.no_stop_required is set (for --images-no-stop-required)
|
||||
# - bkp_docker_2_loc_disabled: All images where backup.disabled is set (for --images-no-backup-required)
|
||||
# - BKP_DOCKER_2_LOC_DB_ROUTINE: All service names where backup.database_routine is set (for --database-containers)
|
||||
# - BKP_DOCKER_2_LOC_NO_STOP_REQUIRED: All images where backup.no_stop_required is set (for --images-no-stop-required)
|
||||
# - BKP_DOCKER_2_LOC_DISABLED: All images where backup.disabled is set (for --images-no-backup-required)
|
||||
# CLI-ready variables render these lists as argument strings.
|
||||
|
||||
BKP_DOCKER_2_LOC_SERVICE: "{{ role_name ~ SYS_SERVICE_SUFFIX }}"
|
||||
|
||||
BKP_DOCKER_2_LOC_SERVICE_ALL: "{{ role_name }}-everything{{ SYS_SERVICE_SUFFIX }}"
|
||||
|
||||
# Verify if DB is enabled
|
||||
bkp_docker_2_loc_db_enabled: "{{ database_type | default('') | bool }}"
|
||||
BKP_DOCKER_2_LOC_DB_ENABLED: "{{ database_type | default('') | bool }}"
|
||||
|
||||
# Gather mapped values as lists
|
||||
bkp_docker_2_loc_database_routine: >-
|
||||
BKP_DOCKER_2_LOC_DB_ROUTINE: >-
|
||||
{{ applications | find_dock_val_by_bkp_entr('database_routine', 'name') | list }}
|
||||
|
||||
bkp_docker_2_loc_no_stop_required: >-
|
||||
BKP_DOCKER_2_LOC_NO_STOP_REQUIRED: >-
|
||||
{{ applications | find_dock_val_by_bkp_entr('no_stop_required', 'image') | list }}
|
||||
|
||||
bkp_docker_2_loc_disabled: >-
|
||||
BKP_DOCKER_2_LOC_DISABLED: >-
|
||||
{{ applications | find_dock_val_by_bkp_entr('disabled', 'image') | list }}
|
||||
|
||||
# CLI argument strings (only set if list not empty)
|
||||
bkp_docker_2_loc_database_routine_cli: >-
|
||||
{% if bkp_docker_2_loc_database_routine | length > 0 -%}
|
||||
--database-containers {{ bkp_docker_2_loc_database_routine | join(' ') }}
|
||||
BKP_DOCKER_2_LOC_DB_ROUTINE_CLI: >-
|
||||
{% if BKP_DOCKER_2_LOC_DB_ROUTINE | length > 0 -%}
|
||||
--database-containers {{ BKP_DOCKER_2_LOC_DB_ROUTINE | join(' ') }}
|
||||
{%- endif %}
|
||||
|
||||
bkp_docker_2_loc_no_stop_required_cli: >-
|
||||
{% if bkp_docker_2_loc_no_stop_required | length > 0 -%}
|
||||
--images-no-stop-required {{ bkp_docker_2_loc_no_stop_required | join(' ') }}
|
||||
BKP_DOCKER_2_LOC_NO_STOP_REQUIRED_CLI: >-
|
||||
{% if BKP_DOCKER_2_LOC_NO_STOP_REQUIRED | length > 0 -%}
|
||||
--images-no-stop-required {{ BKP_DOCKER_2_LOC_NO_STOP_REQUIRED | join(' ') }}
|
||||
{%- endif %}
|
||||
|
||||
bkp_docker_2_loc_disabled_cli: >-
|
||||
{% if bkp_docker_2_loc_disabled | length > 0 -%}
|
||||
--images-no-backup-required {{ bkp_docker_2_loc_disabled | join(' ') }}
|
||||
BKP_DOCKER_2_LOC_DISABLED_CLI: >-
|
||||
{% if BKP_DOCKER_2_LOC_DISABLED | length > 0 -%}
|
||||
--images-no-backup-required {{ BKP_DOCKER_2_LOC_DISABLED | join(' ') }}
|
||||
{%- endif %}
|
||||
|
||||
# List of CLI args for convenience (e.g. for looping or joining)
|
||||
bkp_docker_2_loc_cli_args_list:
|
||||
- "{{ bkp_docker_2_loc_database_routine_cli }}"
|
||||
- "{{ bkp_docker_2_loc_no_stop_required_cli }}"
|
||||
- "{{ bkp_docker_2_loc_disabled_cli }}"
|
||||
BKP_DOCKER_2_LOC_CLI_ARGS_LIST:
|
||||
- "{{ BKP_DOCKER_2_LOC_DB_ROUTINE_CLI }}"
|
||||
- "{{ BKP_DOCKER_2_LOC_NO_STOP_REQUIRED_CLI }}"
|
||||
- "{{ BKP_DOCKER_2_LOC_DISABLED_CLI }}"
|
||||
|
||||
bkp_docker_2_loc_exec: >-
|
||||
BKP_DOCKER_2_LOC_EXEC: >-
|
||||
/usr/bin/python {{ backup_docker_to_local_folder }}backup-docker-to-local.py
|
||||
--compose-dir {{ PATH_DOCKER_COMPOSE_INSTANCES }}
|
||||
{{ bkp_docker_2_loc_cli_args_list | select('string') | join(' ') }}
|
||||
{{ BKP_DOCKER_2_LOC_CLI_ARGS_LIST | select('string') | join(' ') }}
|
||||
|
@@ -4,5 +4,5 @@ OnFailure=sys-alm-compose.{{ SOFTWARE_NAME }}@%n.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStartPre=/bin/sh -c '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ system_maintenance_services | join(' ') }} --ignore {{system_maintenance_cleanup_services| join(' ') }} --timeout "{{system_maintenance_lock_timeout_backup_services}}"'
|
||||
ExecStartPre=/bin/sh -c '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ system_maintenance_services | join(' ') }} --ignore {{system_maintenance_cleanup_services| join(' ') }} --timeout "{{ system_maintenance_lock_timeout_backup_services }}"'
|
||||
ExecStart=/bin/sh -c '/usr/bin/python {{cleanup_backups_directory}}sys-cln-backups.py --backups-folder-path {{backups_folder_path}} --maximum-backup-size-percent {{size_percent_maximum_backup}}'
|
@@ -4,5 +4,5 @@ OnFailure=sys-alm-compose.{{ SOFTWARE_NAME }}@%n.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStartPre=/bin/sh -c '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ system_maintenance_services | join(' ') }} --ignore {{system_maintenance_cleanup_services| join(' ') }} --timeout "{{system_maintenance_lock_timeout_backup_services}}"'
|
||||
ExecStartPre=/bin/sh -c '/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ system_maintenance_services | join(' ') }} --ignore {{system_maintenance_cleanup_services| join(' ') }} --timeout "{{ system_maintenance_lock_timeout_backup_services }}"'
|
||||
ExecStart=/bin/sh -c '/bin/bash {{cleanup_disc_space_folder}}sys-cln-disc-space.sh {{size_percent_cleanup_disc_space}}'
|
@@ -19,7 +19,7 @@ CRON_DISABLED=true
|
||||
# ------------------------------------------------
|
||||
# Initial admin account
|
||||
# ------------------------------------------------
|
||||
ESPOCRM_ADMIN_USERNAME={{ applications | get_app_conf(application_id, 'users.administrator.username', True) }}
|
||||
ESPOCRM_ADMIN_USERNAME={{ applications | get_app_conf(application_id, 'users.administrator.username') }}
|
||||
ESPOCRM_ADMIN_PASSWORD={{ applications | get_app_conf(application_id, 'credentials.administrator_password', True) }}
|
||||
|
||||
# Public base URL of the EspoCRM instance
|
||||
|
@@ -2,7 +2,7 @@
|
||||
# https://github.com/LDAPAccountManager/lam/blob/develop/lam-packaging/docker/.env
|
||||
|
||||
# Basic Configuration
|
||||
LAM_PASSWORD= {{applications | get_app_conf(application_id, 'credentials.administrator_password', True)}} # LAM configuration master password and password for server profile "lam
|
||||
LAM_PASSWORD= {{ applications | get_app_conf(application_id, 'credentials.administrator_password') }} # LAM configuration master password and password for server profile "lam
|
||||
|
||||
# Database
|
||||
LAM_CONFIGURATION_DATABASE= files # configuration database (files or mysql) @todo implement mariadb
|
||||
|
@@ -1,10 +1,9 @@
|
||||
actions:
|
||||
import_realm: True # Import REALM
|
||||
update_ldap_bind: True # Updates LDAP binds
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
desktop: true
|
||||
desktop: true
|
||||
ldap: true
|
||||
central_database: true
|
||||
recaptcha: true
|
||||
|
@@ -1,19 +0,0 @@
|
||||
- name: "load variables from {{ DOCKER_VARS_FILE }}"
|
||||
include_vars: "{{ DOCKER_VARS_FILE }}"
|
||||
|
||||
- name: Set the directory to which keycloak import files will be copied on host
|
||||
set_fact:
|
||||
keycloak_host_import_directory: "{{ docker_compose.directories.volumes }}import/"
|
||||
|
||||
- name: "create directory {{ keycloak_host_import_directory }}"
|
||||
file:
|
||||
path: "{{ keycloak_host_import_directory }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: "Copy import files to {{ keycloak_host_import_directory }}"
|
||||
template:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ keycloak_host_import_directory }}/{{ item | basename | regex_replace('\\.j2$', '') }}"
|
||||
mode: "0770"
|
||||
loop: "{{ lookup('fileglob', role_path ~ '/templates/import/*.j2', wantlist=True) }}"
|
15
roles/web-app-keycloak/tasks/01_initialize.yml
Normal file
15
roles/web-app-keycloak/tasks/01_initialize.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
- name: "load variables from {{ DOCKER_VARS_FILE }}"
|
||||
include_vars: "{{ DOCKER_VARS_FILE }}"
|
||||
|
||||
- name: "create directory {{ KEYCLOAK_HOST_IMPORT_DIR }}"
|
||||
file:
|
||||
path: "{{ KEYCLOAK_HOST_IMPORT_DIR }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: "Copy import files to {{ KEYCLOAK_HOST_IMPORT_DIR }}"
|
||||
template:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ KEYCLOAK_HOST_IMPORT_DIR }}/{{ item | basename | regex_replace('\\.j2$', '') }}"
|
||||
mode: "0770"
|
||||
loop: "{{ lookup('fileglob', role_path ~ '/templates/import/*.j2', wantlist=True) }}"
|
107
roles/web-app-keycloak/tasks/02_update.yml
Normal file
107
roles/web-app-keycloak/tasks/02_update.yml
Normal file
@@ -0,0 +1,107 @@
|
||||
# Generic updater for Keycloak client/component via kcadm.
|
||||
# Flow: resolve ID → read current object → merge with desired → preserve immutable fields → update via stdin.
|
||||
#
|
||||
# Required vars (pass via include):
|
||||
# - kc_object_kind: "client" | "component"
|
||||
# - kc_lookup_value: e.g., KEYCLOAK_CLIENT_ID or KEYCLOAK_LDAP_CMP_NAME
|
||||
# - kc_desired: dict, e.g., KEYCLOAK_DICTIONARY_CLIENT or KEYCLOAK_DICTIONARY_LDAP
|
||||
#
|
||||
# Optional:
|
||||
# - kc_lookup_field: override lookup field (defaults: clientId for client, name for component)
|
||||
# - kc_merge_path: if set (e.g. "config"), only that subkey is merged
|
||||
# - kc_force_attrs: dict to force on the final payload (merged last)
|
||||
|
||||
- name: Assert required vars
|
||||
assert:
|
||||
that:
|
||||
- kc_object_kind in ['client','component']
|
||||
- kc_lookup_value is defined
|
||||
- kc_desired is defined
|
||||
fail_msg: "kc_object_kind, kc_lookup_value, kc_desired are required."
|
||||
|
||||
- name: Derive API endpoint and lookup field
|
||||
set_fact:
|
||||
kc_api: "{{ 'clients' if kc_object_kind == 'client' else 'components' }}"
|
||||
kc_lookup_field_eff: "{{ 'clientId' if kc_object_kind == 'client' else (kc_lookup_field | default('name')) }}"
|
||||
|
||||
- name: Resolve object id
|
||||
shell: >
|
||||
{{ KEYCLOAK_EXEC_KCADM }} get {{ kc_api }}
|
||||
-r {{ KEYCLOAK_REALM }}
|
||||
--query '{{ kc_lookup_field_eff }}={{ kc_lookup_value }}'
|
||||
--fields id --format json | jq -r '.[0].id'
|
||||
register: kc_obj_id
|
||||
changed_when: false
|
||||
|
||||
- name: Fail if object not found
|
||||
assert:
|
||||
that:
|
||||
- (kc_obj_id.stdout | trim) != ''
|
||||
- (kc_obj_id.stdout | trim) != 'null'
|
||||
fail_msg: "{{ kc_object_kind | capitalize }} '{{ kc_lookup_value }}' not found."
|
||||
|
||||
- name: Read current object
|
||||
shell: >
|
||||
{{ KEYCLOAK_EXEC_KCADM }} get {{ kc_api }}/{{ kc_obj_id.stdout }}
|
||||
-r {{ KEYCLOAK_REALM }} --format json
|
||||
register: kc_cur
|
||||
changed_when: false
|
||||
|
||||
# ── Build merge payload safely (avoid evaluating kc_desired[kc_merge_path] when undefined) ─────────
|
||||
|
||||
- name: Parse current object
|
||||
set_fact:
|
||||
cur_obj: "{{ kc_cur.stdout | from_json }}"
|
||||
|
||||
- name: Prepare merge payload (subpath)
|
||||
when: kc_merge_path is defined and (kc_merge_path | length) > 0
|
||||
set_fact:
|
||||
merge_payload: "{{ { (kc_merge_path): (kc_desired[kc_merge_path] | default({}, true)) } }}"
|
||||
|
||||
- name: Prepare merge payload (full object)
|
||||
when: kc_merge_path is not defined or (kc_merge_path | length) == 0
|
||||
set_fact:
|
||||
merge_payload: "{{ kc_desired }}"
|
||||
|
||||
- name: Build desired object (base merge)
|
||||
set_fact:
|
||||
desired_obj: "{{ cur_obj | combine(merge_payload, recursive=True) }}"
|
||||
|
||||
# Preserve immutable fields
|
||||
- name: Preserve immutable fields for client
|
||||
when: kc_object_kind == 'client'
|
||||
set_fact:
|
||||
desired_obj: >-
|
||||
{{
|
||||
desired_obj
|
||||
| combine({
|
||||
'id': cur_obj.id,
|
||||
'clientId': cur_obj.clientId
|
||||
}, recursive=True)
|
||||
}}
|
||||
|
||||
- name: Preserve immutable fields for component
|
||||
when: kc_object_kind == 'component'
|
||||
set_fact:
|
||||
desired_obj: >-
|
||||
{{
|
||||
desired_obj
|
||||
| combine({
|
||||
'id': cur_obj.id,
|
||||
'providerId': cur_obj.providerId,
|
||||
'providerType': cur_obj.providerType,
|
||||
'parentId': cur_obj.parentId
|
||||
}, recursive=True)
|
||||
}}
|
||||
|
||||
# Optional forced attributes (e.g., frontchannelLogout)
|
||||
- name: Apply forced attributes (optional)
|
||||
when: kc_force_attrs is defined
|
||||
set_fact:
|
||||
desired_obj: "{{ desired_obj | combine(kc_force_attrs, recursive=True) }}"
|
||||
|
||||
- name: Update object via stdin
|
||||
shell: |
|
||||
cat <<'JSON' | {{ KEYCLOAK_EXEC_KCADM }} update {{ kc_api }}/{{ kc_obj_id.stdout }} -r {{ KEYCLOAK_REALM }} -f -
|
||||
{{ desired_obj | to_json }}
|
||||
JSON
|
@@ -1,118 +0,0 @@
|
||||
---
|
||||
# Update redirectUris/webOrigins per kcadm.sh — no defaults used.
|
||||
|
||||
# ── REQUIRED VARS (must be provided by caller) ───────────────────────────────
|
||||
# - WEB_PROTOCOL e.g. "https"
|
||||
# - keycloak_realm target realm name
|
||||
# - keycloak_server_host_url e.g. "http://127.0.0.1:8080"
|
||||
# - keycloak_server_internal_url e.g. "http://127.0.0.1:8080"
|
||||
# - keycloak_kcadm_path e.g. "docker exec -i keycloak /opt/keycloak/bin/kcadm.sh"
|
||||
# - keycloak_master_api_user_name
|
||||
# - keycloak_master_api_user_password
|
||||
# - keycloak_client_id clientId to update (e.g. same as realm or an app client)
|
||||
# - domains your domain map
|
||||
# - applications your applications map
|
||||
|
||||
- name: "Assert required variables are present (no defaults allowed)"
|
||||
assert:
|
||||
that:
|
||||
- WEB_PROTOCOL is defined
|
||||
- keycloak_realm is defined
|
||||
- keycloak_server_host_url is defined
|
||||
- keycloak_server_internal_url is defined
|
||||
- keycloak_kcadm_path is defined
|
||||
- keycloak_master_api_user_name is defined
|
||||
- keycloak_master_api_user_password is defined
|
||||
- keycloak_client_id is defined
|
||||
- keycloak_redirect_features is defined
|
||||
- domains is defined
|
||||
- applications is defined
|
||||
fail_msg: "Missing required variable(s). Provide all vars listed at the top of 02_update_client_redirects.yml."
|
||||
|
||||
- name: "kcadm login"
|
||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||
shell: >
|
||||
{{ keycloak_kcadm_path }} config credentials
|
||||
--server {{ keycloak_server_internal_url }}
|
||||
--realm master
|
||||
--user {{ keycloak_master_api_user_name }}
|
||||
--password {{ keycloak_master_api_user_password }}
|
||||
changed_when: false
|
||||
|
||||
# 1) Build desired sets (NO defaults)
|
||||
- name: "Build desired redirect URIs from config via filter"
|
||||
set_fact:
|
||||
kc_redirect_uris: >-
|
||||
{{ domains | redirect_uris(applications, WEB_PROTOCOL, '/*', keycloak_redirect_features, True) }}
|
||||
|
||||
- name: Build desired web origins (scheme://host[:port])
|
||||
set_fact:
|
||||
kc_web_origins: >-
|
||||
{{ kc_redirect_uris
|
||||
| map('regex_replace','/\\*$','')
|
||||
| map('regex_search','^(https?://[^/]+)')
|
||||
| select('string')
|
||||
| list | unique }}
|
||||
|
||||
#- name: "Build post.logout.redirect.uris value ('+' plus explicit URIs without /*)"
|
||||
# set_fact:
|
||||
# kc_desired_post_logout_uris: >-
|
||||
# {{ (['+'] + (kc_redirect_uris | map('regex_replace','/\\*$','') | list)) | join('\n') }}
|
||||
|
||||
# 2) Resolve client id (strictly by provided clientId, no fallback)
|
||||
- name: "Resolve client internal id for {{ keycloak_client_id }}"
|
||||
shell: >
|
||||
{{ keycloak_kcadm_path }} get clients
|
||||
-r {{ keycloak_realm }}
|
||||
--query 'clientId={{ keycloak_client_id }}'
|
||||
--fields id --format json | jq -r '.[0].id'
|
||||
register: kc_client
|
||||
changed_when: false
|
||||
|
||||
- name: "Fail if client not found"
|
||||
assert:
|
||||
that: kc_client.stdout is match('^[0-9a-f-]+$')
|
||||
fail_msg: "Client '{{ keycloak_client_id }}' not found in realm '{{ keycloak_realm }}'."
|
||||
|
||||
# 3) Read current config (assume keys exist; we don't use defaults)
|
||||
- name: "Read current client configuration"
|
||||
shell: >
|
||||
{{ keycloak_kcadm_path }} get clients/{{ kc_client.stdout }}
|
||||
-r {{ keycloak_realm }} --format json
|
||||
register: kc_client_obj
|
||||
changed_when: false
|
||||
|
||||
- name: "Normalize current vs desired for comparison"
|
||||
set_fact:
|
||||
kc_current_redirect_uris: "{{ (kc_client_obj.stdout | from_json).redirectUris | sort }}"
|
||||
kc_current_web_origins: "{{ (kc_client_obj.stdout | from_json).webOrigins | sort }}"
|
||||
kc_current_logout_uris: >-
|
||||
{{
|
||||
(
|
||||
(kc_client_obj.stdout | from_json).attributes['post.logout.redirect.uris']
|
||||
if 'post.logout.redirect.uris' in (kc_client_obj.stdout | from_json).attributes
|
||||
else ''
|
||||
)
|
||||
| regex_replace('\r','')
|
||||
| split('\n')
|
||||
| reject('equalto','')
|
||||
| list | sort
|
||||
}}
|
||||
kc_desired_redirect_uris: "{{ kc_redirect_uris | sort }}"
|
||||
kc_desired_web_origins: "{{ kc_web_origins | sort }}"
|
||||
kc_desired_post_logout_uris: "+"
|
||||
kc_desired_post_logout_uris_list: >-
|
||||
{{ "+" | split('\n') | reject('equalto','') | list | sort }}
|
||||
|
||||
# 4) Update only when changed
|
||||
- name: "Update redirectUris, webOrigins, post.logout.redirect.uris"
|
||||
shell: >
|
||||
{{ keycloak_kcadm_path }} update clients/{{ kc_client.stdout }}
|
||||
-r {{ keycloak_realm }}
|
||||
-s 'redirectUris={{ kc_redirect_uris | to_json }}'
|
||||
-s 'webOrigins={{ kc_web_origins | to_json }}'
|
||||
-s 'attributes."post.logout.redirect.uris"={{ kc_desired_post_logout_uris | to_json }}'
|
||||
when: kc_current_redirect_uris != kc_desired_redirect_uris
|
||||
or kc_current_web_origins != kc_desired_web_origins
|
||||
or kc_current_logout_uris != kc_desired_post_logout_uris_list
|
||||
|
@@ -1,118 +0,0 @@
|
||||
---
|
||||
# Idempotent update of Keycloak LDAP provider:
|
||||
# - bindDn
|
||||
# - bindCredential
|
||||
# - connectionUrl
|
||||
#
|
||||
# STRICT: Uses ONLY values from ldap.* (no computed defaults)
|
||||
# - ldap.dn.administrator.data
|
||||
# - ldap.bind_credential
|
||||
# - ldap.server.uri
|
||||
|
||||
- name: "Assert required vars exist (strict: use ldap.* only, no defaults)"
|
||||
assert:
|
||||
that:
|
||||
- keycloak_realm is defined
|
||||
- keycloak_container is defined
|
||||
- keycloak_server_internal_url is defined
|
||||
- keycloak_master_api_user_name is defined
|
||||
- keycloak_master_api_user_password is defined
|
||||
- keycloak_ldap_component_name is defined
|
||||
- ldap is defined
|
||||
- ldap.dn.administrator is defined
|
||||
- ldap.dn.administrator.data is defined
|
||||
- ldap.bind_credential is defined
|
||||
- ldap.server is defined
|
||||
- ldap.server.uri is defined
|
||||
fail_msg: >-
|
||||
Missing required Keycloak/LDAP variables. Ensure ldap.dn.administrator.data,
|
||||
ldap.bind_credential, and ldap.server.uri are defined.
|
||||
|
||||
# Build a base argv for kcadm to avoid fragile shell quoting
|
||||
- name: "Build kcadm argv base"
|
||||
set_fact:
|
||||
kcadm_argv_base:
|
||||
- docker
|
||||
- exec
|
||||
- -i
|
||||
- "{{ keycloak_container }}"
|
||||
- /opt/keycloak/bin/kcadm.sh
|
||||
|
||||
- name: "kcadm login (master)"
|
||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||
command:
|
||||
argv: "{{ kcadm_argv_base
|
||||
+ ['config', 'credentials',
|
||||
'--server', keycloak_server_internal_url,
|
||||
'--realm', 'master',
|
||||
'--user', keycloak_master_api_user_name,
|
||||
'--password', keycloak_master_api_user_password] }}"
|
||||
changed_when: false
|
||||
|
||||
# Resolve the LDAP component *by name* to avoid picking the wrong one.
|
||||
- name: "Resolve LDAP component id by name '{{ keycloak_ldap_component_name }}'"
|
||||
command:
|
||||
argv: "{{ kcadm_argv_base
|
||||
+ ['get', 'components',
|
||||
'-r', keycloak_realm,
|
||||
'--query', 'name=' ~ keycloak_ldap_component_name,
|
||||
'--fields', 'id,name,providerId,config',
|
||||
'--format', 'json'] }}"
|
||||
register: kc_ldap_list
|
||||
changed_when: false
|
||||
|
||||
- name: "Validate that exactly one LDAP component matched"
|
||||
vars:
|
||||
parsed: "{{ kc_ldap_list.stdout | from_json }}"
|
||||
assert:
|
||||
that:
|
||||
- (parsed | length) == 1
|
||||
fail_msg: >-
|
||||
Expected exactly one LDAP component named '{{ keycloak_ldap_component_name }}',
|
||||
found {{ (kc_ldap_list.stdout | from_json) | length }}.
|
||||
|
||||
- name: "Extract current LDAP component values"
|
||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||
set_fact:
|
||||
kc_ldap_component_id: "{{ (kc_ldap_list.stdout | from_json)[0].id }}"
|
||||
kc_ldap_current_bind_dn: "{{ ((kc_ldap_list.stdout | from_json)[0].config['bindDn'] | default(['']))[0] }}"
|
||||
kc_ldap_current_bind_pw: "{{ ((kc_ldap_list.stdout | from_json)[0].config['bindCredential'] | default(['']))[0] }}"
|
||||
kc_ldap_current_connection_url: "{{ ((kc_ldap_list.stdout | from_json)[0].config['connectionUrl'] | default(['']))[0] }}"
|
||||
|
||||
# Desired values come STRICTLY from ldap.*
|
||||
- name: "Set desired LDAP values (strict from ldap.*)"
|
||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||
set_fact:
|
||||
kc_desired_bind_dn: "{{ ldap.dn.administrator.data }}"
|
||||
kc_desired_bind_pw: "{{ ldap.bind_credential }}"
|
||||
kc_desired_connection_url: "{{ ldap.server.uri }}"
|
||||
|
||||
- name: "Determine if update is required"
|
||||
set_fact:
|
||||
kc_needs_update: >-
|
||||
{{
|
||||
(kc_ldap_current_bind_dn != kc_desired_bind_dn)
|
||||
or (kc_ldap_current_bind_pw != kc_desired_bind_pw)
|
||||
or (kc_ldap_current_connection_url != kc_desired_connection_url)
|
||||
}}
|
||||
|
||||
# Pass each -s as a single argv token with valid JSON (arrays), zero shell quoting issues.
|
||||
- name: "Update LDAP bindDn / bindCredential / connectionUrl (strict, argv)"
|
||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||
command:
|
||||
argv: "{{ kcadm_argv_base
|
||||
+ ['update', 'components/' ~ kc_ldap_component_id,
|
||||
'-r', keycloak_realm,
|
||||
'-s', 'config.bindDn=' ~ ([kc_desired_bind_dn] | to_json),
|
||||
'-s', 'config.bindCredential=' ~ ([kc_desired_bind_pw] | to_json),
|
||||
'-s', 'config.connectionUrl=' ~ ([kc_desired_connection_url] | to_json)
|
||||
] }}"
|
||||
when: kc_needs_update | bool
|
||||
register: kc_bind_update
|
||||
|
||||
- name: "LDAP provider updated"
|
||||
debug:
|
||||
msg: "LDAP bindDn/bindCredential/connectionUrl updated on component {{ keycloak_ldap_component_name }}."
|
||||
when:
|
||||
- kc_bind_update is defined
|
||||
- kc_bind_update.rc == 0
|
@@ -1,71 +0,0 @@
|
||||
# Configure Credentials
|
||||
- name: Ensure Keycloak CLI credentials are configured
|
||||
shell: |
|
||||
{{ keycloak_kcadm_path }} config credentials \
|
||||
--server {{ keycloak_server_internal_url }} \
|
||||
--realm master \
|
||||
--user {{ keycloak_master_api_user_name }} \
|
||||
--password {{ keycloak_master_api_user_password }}
|
||||
|
||||
# LDAP Source
|
||||
- name: Get ID of LDAP storage provider
|
||||
shell: |
|
||||
{{ keycloak_kcadm_path }} get components \
|
||||
-r {{ keycloak_realm }} \
|
||||
--query 'providerId=ldap' \
|
||||
--fields id,name \
|
||||
--format json
|
||||
register: ldap_components
|
||||
|
||||
- name: Extract LDAP component ID
|
||||
set_fact:
|
||||
ldap_component_id: "{{ (ldap_components.stdout | from_json)[0].id }}"
|
||||
|
||||
- name: Ensure {{ ldap.user.attributes.ssh_public_key }} LDAP Mapper exists
|
||||
shell: |
|
||||
docker exec -i keycloak_application bash -c '
|
||||
/opt/keycloak/bin/kcadm.sh get components -r {{ keycloak_realm }} \
|
||||
| grep -q "\"name\" : \"{{ ldap.user.attributes.ssh_public_key }}\"" \
|
||||
|| printf "%s\n" "{
|
||||
\"name\": \"{{ ldap.user.attributes.ssh_public_key }}\",
|
||||
\"parentId\": \"{{ ldap_component_id }}\",
|
||||
\"providerId\": \"user-attribute-ldap-mapper\",
|
||||
\"providerType\": \"org.keycloak.storage.ldap.mappers.LDAPStorageMapper\",
|
||||
\"config\": {
|
||||
\"user.model.attribute\": [\"{{ ldap.user.attributes.ssh_public_key }}\"],
|
||||
\"ldap.attribute\": [\"{{ ldap.user.attributes.ssh_public_key }}\"],
|
||||
\"read.only\": [\"false\"],
|
||||
\"write.only\": [\"true\"],
|
||||
\"always.read.value.from.ldap\": [\"false\"],
|
||||
\"multivalued\": [\"true\"]
|
||||
}
|
||||
}" | /opt/keycloak/bin/kcadm.sh create components -r {{ keycloak_realm }} -f -'
|
||||
register: mapper_create
|
||||
changed_when: mapper_create.rc == 0 and mapper_create.stdout != ""
|
||||
|
||||
# GUI
|
||||
|
||||
- name: Enable user profile in realm
|
||||
shell: >
|
||||
{{ keycloak_kcadm_path }} update realms/{{ keycloak_realm }}
|
||||
-s 'attributes.userProfileEnabled=true'
|
||||
|
||||
- name: Re-authenticate to Keycloak after enabling user profile
|
||||
shell: |
|
||||
{{ keycloak_kcadm_path }} config credentials \
|
||||
--server {{ keycloak_server_internal_url }} \
|
||||
--realm master \
|
||||
--user {{ keycloak_master_api_user_name }} \
|
||||
--password {{ keycloak_master_api_user_password }}
|
||||
|
||||
- name: Render user-profile JSON for SSH key
|
||||
template:
|
||||
src: import/user-profile.json.j2
|
||||
dest: "{{ keycloak_host_import_directory }}/user-profile.json"
|
||||
mode: '0644'
|
||||
notify: docker compose up
|
||||
|
||||
- name: Apply SSH Public Key to user-profile via kcadm
|
||||
shell: |
|
||||
docker exec -i {{ keycloak_container }} \
|
||||
/opt/keycloak/bin/kcadm.sh update realms/{{ keycloak_realm }} -f {{ keycloak_docker_import_directory }}user-profile.json
|
@@ -1,3 +1,3 @@
|
||||
# Todos
|
||||
- Include 03_update-ldap-bind.yml
|
||||
- Include 03_update-ldap.yml
|
||||
- Include 04_ssh_public_key.yml
|
@@ -1,6 +1,6 @@
|
||||
---
|
||||
- name: "create import files for {{ application_id }}"
|
||||
include_tasks: 01_import.yml
|
||||
include_tasks: 01_initialize.yml
|
||||
|
||||
- name: "load required 'web-svc-logout' for {{ application_id }}"
|
||||
include_role:
|
||||
@@ -10,10 +10,12 @@
|
||||
- name: "load docker, db and proxy for {{ application_id }}"
|
||||
include_role:
|
||||
name: cmp-db-docker-proxy
|
||||
vars:
|
||||
docker_compose_flush_handlers: true
|
||||
|
||||
- name: "Wait until Keycloak is reachable at {{ keycloak_server_host_url }}"
|
||||
- name: "Wait until Keycloak is reachable at {{ KEYCLOAK_SERVER_HOST_URL }}"
|
||||
uri:
|
||||
url: "{{ keycloak_server_host_url }}/realms/master"
|
||||
url: "{{ KEYCLOAK_MASTER_REALM_URL }}"
|
||||
method: GET
|
||||
status_code: 200
|
||||
validate_certs: false
|
||||
@@ -22,13 +24,41 @@
|
||||
delay: 5
|
||||
until: kc_up.status == 200
|
||||
|
||||
- name: "Apply client redirects without realm import"
|
||||
include_tasks: 02_update_client_redirects.yml
|
||||
- name: kcadm login (master)
|
||||
no_log: true
|
||||
shell: >
|
||||
{{ KEYCLOAK_EXEC_KCADM }} config credentials
|
||||
--server {{ KEYCLOAK_SERVER_INTERNAL_URL }}
|
||||
--realm master
|
||||
--user {{ KEYCLOAK_MASTER_API_USER_NAME }}
|
||||
--password {{ KEYCLOAK_MASTER_API_USER_PASSWORD }}
|
||||
changed_when: false
|
||||
|
||||
- name: "Update LDAP bind credentials from ldap.*"
|
||||
when: keycloak_update_ldap_bind | bool
|
||||
include_tasks: 03_update-ldap-bind.yml
|
||||
- name: "Update REALM settings"
|
||||
include_tasks: 02_update.yml
|
||||
vars:
|
||||
kc_object_kind: "component"
|
||||
kc_lookup_value: "{{ KEYCLOAK_LDAP_CMP_NAME }}"
|
||||
kc_desired: >-
|
||||
{{
|
||||
KEYCLOAK_DICTIONARY_REALM.components['org.keycloak.storage.UserStorageProvider']
|
||||
| selectattr('providerId','equalto','ldap')
|
||||
| list | first }}
|
||||
kc_merge_path: "config"
|
||||
when: KEYCLOAK_LDAP_ENABLED | bool
|
||||
|
||||
# Deactivated temporary. Import now via realm.yml
|
||||
#- name: Implement SSH Public Key Attribut
|
||||
# include_tasks: 03_ssh_public_key.yml
|
||||
- name: "Update Client settings"
|
||||
vars:
|
||||
kc_object_kind: "client"
|
||||
kc_lookup_value: "{{ KEYCLOAK_CLIENT_ID }}"
|
||||
kc_desired: >-
|
||||
{{
|
||||
KEYCLOAK_DICTIONARY_REALM.clients
|
||||
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
||||
| list | first
|
||||
}}
|
||||
kc_force_attrs:
|
||||
frontchannelLogout: true
|
||||
attributes: "{{ (KEYCLOAK_DICTIONARY_CLIENT.attributes | default({}))
|
||||
| combine({'frontchannel.logout.url': KEYCLOAK_FRONTCHANNEL_LOGOUT_URL}, recursive=True) }}"
|
||||
include_tasks: 02_update.yml
|
||||
|
@@ -1,14 +1,14 @@
|
||||
{% include 'roles/docker-compose/templates/base.yml.j2' %}
|
||||
|
||||
application:
|
||||
image: "{{ keycloak_image }}:{{ keycloak_version }}"
|
||||
container_name: {{ keycloak_container }}
|
||||
command: start{% if keycloak_import_realm %} --import-realm{% endif %}{% if keycloak_debug_enabled %} --verbose{% endif %}
|
||||
image: "{{ KEYCLOAK_IMAGE }}:{{ KEYCLOAK_VERSION }}"
|
||||
container_name: {{ KEYCLOAK_CONTAINER }}
|
||||
command: start{% if KEYCLOAK_IMPORT_REALM_ENABLED %} --import-realm{% endif %}{% if KEYCLOAK_DEBUG_ENABLED %} --verbose{% endif %}
|
||||
{% include 'roles/docker-container/templates/base.yml.j2' %}
|
||||
ports:
|
||||
- "{{ keycloak_server_host }}:8080"
|
||||
- "{{ KEYCLOAK_SERVER_HOST }}:8080"
|
||||
volumes:
|
||||
- "{{ keycloak_host_import_directory }}:{{keycloak_docker_import_directory}}"
|
||||
- "{{ KEYCLOAK_HOST_IMPORT_DIR }}:{{KEYCLOAK_DOCKER_IMPORT_DIR}}"
|
||||
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
|
||||
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
||||
{% set container_port = 9000 %}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
# Documentation can be found here:
|
||||
# @see https://www.keycloak.org/server/containers
|
||||
|
||||
KC_HOSTNAME= https://{{ domains | get_domain(application_id) }}
|
||||
KC_HOSTNAME= {{ KEYCLOAK_URL }}
|
||||
KC_HTTP_ENABLED= true
|
||||
|
||||
# Health Checks
|
||||
@@ -11,18 +11,18 @@ KC_HEALTH_ENABLED= true
|
||||
KC_METRICS_ENABLED= true
|
||||
|
||||
# Administrator
|
||||
KEYCLOAK_ADMIN= "{{applications | get_app_conf(application_id, 'users.administrator.username', True)}}"
|
||||
KEYCLOAK_ADMIN_PASSWORD= "{{applications | get_app_conf(application_id, 'credentials.administrator_password', True)}}"
|
||||
KEYCLOAK_ADMIN= "{{ KEYCLOAK_ADMIN }}"
|
||||
KEYCLOAK_ADMIN_PASSWORD= "{{ KEYCLOAK_ADMIN_PASSWORD }}"
|
||||
|
||||
# Database
|
||||
KC_DB= postgres
|
||||
KC_DB_URL= {{database_url_jdbc}}
|
||||
KC_DB= {{ database_type }}
|
||||
KC_DB_URL= {{ database_url_jdbc }}
|
||||
KC_DB_USERNAME= {{ database_username }}
|
||||
KC_DB_PASSWORD= {{ database_password }}
|
||||
|
||||
# If the initial administrator already exists and the environment variables are still present at startup, an error message stating the failed creation of the initial administrator is shown in the logs. Keycloak ignores the values and starts up correctly.
|
||||
KC_BOOTSTRAP_ADMIN_USERNAME= "{{applications | get_app_conf(application_id, 'users.administrator.username', True)}}"
|
||||
KC_BOOTSTRAP_ADMIN_PASSWORD= "{{applications | get_app_conf(application_id, 'credentials.administrator_password', True)}}"
|
||||
KC_BOOTSTRAP_ADMIN_USERNAME= "{{ KEYCLOAK_ADMIN }}"
|
||||
KC_BOOTSTRAP_ADMIN_PASSWORD= "{{ KEYCLOAK_ADMIN_PASSWORD }}"
|
||||
|
||||
# Enable detailed logs
|
||||
{% if MODE_DEBUG | bool %}
|
||||
|
59
roles/web-app-keycloak/templates/import/client.json.j2
Normal file
59
roles/web-app-keycloak/templates/import/client.json.j2
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"clientId": "{{ KEYCLOAK_CLIENT_ID }}",
|
||||
"name": "",
|
||||
"description": "",
|
||||
"rootUrl": "{{ KEYCLOAK_REALM_URL }}",
|
||||
"adminUrl": "{{ KEYCLOAK_REALM_URL }}",
|
||||
"baseUrl": "{{ KEYCLOAK_REALM_URL }}",
|
||||
"surrogateAuthRequired": false,
|
||||
"enabled": true,
|
||||
"alwaysDisplayInConsole": false,
|
||||
"clientAuthenticatorType": "client-secret",
|
||||
"secret": "{{ OIDC.CLIENT.SECRET }}",
|
||||
"redirectUris": {{ KEYCLOAK_REDIRECT_URIS | to_json }},
|
||||
"webOrigins": {{ KEYCLOAK_WEB_ORIGINS | to_json }},
|
||||
"notBefore": 0,
|
||||
"bearerOnly": false,
|
||||
"consentRequired": false,
|
||||
"standardFlowEnabled": true,
|
||||
"implicitFlowEnabled": true,
|
||||
"directAccessGrantsEnabled": true,
|
||||
"serviceAccountsEnabled": true,
|
||||
"publicClient": false,
|
||||
"frontchannelLogout": true,
|
||||
"protocol": "openid-connect",
|
||||
"attributes": {
|
||||
"frontchannel.logout.url": {{ KEYCLOAK_FRONTCHANNEL_LOGOUT_URL | to_json }},
|
||||
"realm_client": "false",
|
||||
"oidc.ciba.grant.enabled": "false",
|
||||
"client.secret.creation.time": "0",
|
||||
"backchannel.logout.session.required": "true",
|
||||
"post.logout.redirect.uris": {{ KEYCLOAK_POST_LOGOUT_URIS | to_json }},
|
||||
"frontchannel.logout.session.required": "true",
|
||||
"oauth2.device.authorization.grant.enabled": "false",
|
||||
"display.on.consent.screen": "false",
|
||||
"use.jwks.url": "false",
|
||||
"backchannel.logout.revoke.offline.tokens": "false"
|
||||
},
|
||||
"authenticationFlowBindingOverrides": {},
|
||||
"fullScopeAllowed": true,
|
||||
"nodeReRegistrationTimeout": -1,
|
||||
"defaultClientScopes": [
|
||||
"web-origins",
|
||||
"service_account",
|
||||
"acr",
|
||||
"roles",
|
||||
"profile",
|
||||
"basic",
|
||||
"email"
|
||||
],
|
||||
"optionalClientScopes": [
|
||||
"address",
|
||||
"phone",
|
||||
"organization",
|
||||
"offline_access",
|
||||
"microprofile-jwt",
|
||||
"{{ applications | get_app_conf(application_id, 'scopes.rbac_roles', True) }}",
|
||||
"{{ applications | get_app_conf(application_id, 'scopes.nextcloud', True) }}"
|
||||
]
|
||||
}
|
227
roles/web-app-keycloak/templates/import/ldap.json.j2
Normal file
227
roles/web-app-keycloak/templates/import/ldap.json.j2
Normal file
@@ -0,0 +1,227 @@
|
||||
{
|
||||
"name": "{{ KEYCLOAK_LDAP_CMP_NAME }}",
|
||||
"providerId": "ldap",
|
||||
"subComponents": {
|
||||
"org.keycloak.storage.ldap.mappers.LDAPStorageMapper": [
|
||||
|
||||
{# ---------------------- First Name ---------------------- #}
|
||||
{
|
||||
"name": "first name",
|
||||
"providerId": "user-attribute-ldap-mapper",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"ldap.attribute": [ "{{ ldap.user.attributes.firstname }}" ],
|
||||
"attribute.force.default": [ "true" ],
|
||||
"is.mandatory.in.ldap": [ "true" ],
|
||||
"is.binary.attribute": [ "false" ],
|
||||
"always.read.value.from.ldap": [ "true" ],
|
||||
"read.only": [ "false" ],
|
||||
"user.model.attribute": [ "firstName" ]
|
||||
}
|
||||
},
|
||||
|
||||
{# ---------------------- Last Name ----------------------- #}
|
||||
{
|
||||
"name": "last name",
|
||||
"providerId": "user-attribute-ldap-mapper",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"ldap.attribute": [ "{{ ldap.user.attributes.surname }}" ],
|
||||
"is.mandatory.in.ldap": [ "true" ],
|
||||
"always.read.value.from.ldap": [ "true" ],
|
||||
"read.only": [ "false" ],
|
||||
"user.model.attribute": [ "lastName" ]
|
||||
}
|
||||
},
|
||||
|
||||
{# ---------------------- Full Name (cn) ------------------ #}
|
||||
{
|
||||
"name": "full name",
|
||||
"providerId": "full-name-ldap-mapper",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"read.only": [ "false" ],
|
||||
"write.only": [ "true" ],
|
||||
"ldap.full.name.attribute": [ "{{ ldap.user.attributes.fullname }}" ]
|
||||
}
|
||||
},
|
||||
|
||||
{# ---------------------- Username ------------------------ #}
|
||||
{
|
||||
"name": "username",
|
||||
"providerId": "user-attribute-ldap-mapper",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"ldap.attribute": [ "{{ ldap.user.attributes.id }}" ],
|
||||
"is.mandatory.in.ldap": [ "true" ],
|
||||
"attribute.force.default": [ "false" ],
|
||||
"is.binary.attribute": [ "false" ],
|
||||
"always.read.value.from.ldap": [ "false" ],
|
||||
"read.only": [ "false" ],
|
||||
"user.model.attribute": [ "username" ]
|
||||
}
|
||||
},
|
||||
|
||||
{# ---------------------- Email --------------------------- #}
|
||||
{
|
||||
"name": "email",
|
||||
"providerId": "user-attribute-ldap-mapper",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"ldap.attribute": [ "{{ ldap.user.attributes.mail }}" ],
|
||||
"is.mandatory.in.ldap": [ "false" ],
|
||||
"read.only": [ "false" ],
|
||||
"always.read.value.from.ldap": [ "false" ],
|
||||
"user.model.attribute": [ "email" ]
|
||||
}
|
||||
},
|
||||
|
||||
{# ---------------------- SSH Public Key ------------------ #}
|
||||
{
|
||||
"name": "SSH Public Key",
|
||||
"providerId": "user-attribute-ldap-mapper",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"ldap.attribute": [ "{{ ldap.user.attributes.ssh_public_key }}" ],
|
||||
"is.mandatory.in.ldap": [ "false" ],
|
||||
"attribute.force.default": [ "false" ],
|
||||
"is.binary.attribute": [ "false" ],
|
||||
"read.only": [ "false" ],
|
||||
"always.read.value.from.ldap": [ "true" ],
|
||||
"user.model.attribute": [ "{{ ldap.user.attributes.ssh_public_key }}" ]
|
||||
}
|
||||
},
|
||||
|
||||
{# ---------------------- Nextcloud Quota ----------------- #}
|
||||
{
|
||||
"name": "{{ ldap.user.attributes.nextcloud_quota }}",
|
||||
"providerId": "user-attribute-ldap-mapper",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"ldap.attribute": [ "{{ ldap.user.attributes.nextcloud_quota }}" ],
|
||||
"is.mandatory.in.ldap": [ "false" ],
|
||||
"attribute.force.default": [ "false" ],
|
||||
"is.binary.attribute": [ "false" ],
|
||||
"always.read.value.from.ldap": [ "false" ],
|
||||
"read.only": [ "false" ],
|
||||
"user.model.attribute": [ "{{ ldap.user.attributes.nextcloud_quota }}" ]
|
||||
}
|
||||
},
|
||||
|
||||
{# ---------------------- Creation Date ------------------- #}
|
||||
{
|
||||
"name": "creation date",
|
||||
"providerId": "user-attribute-ldap-mapper",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"ldap.attribute": [ "createTimestamp" ],
|
||||
"is.mandatory.in.ldap": [ "false" ],
|
||||
"always.read.value.from.ldap": [ "true" ],
|
||||
"read.only": [ "true" ],
|
||||
"user.model.attribute": [ "createTimestamp" ]
|
||||
}
|
||||
},
|
||||
|
||||
{# ---------------------- Modify Date --------------------- #}
|
||||
{
|
||||
"name": "modify date",
|
||||
"providerId": "user-attribute-ldap-mapper",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"ldap.attribute": [ "modifyTimestamp" ],
|
||||
"is.mandatory.in.ldap": [ "false" ],
|
||||
"always.read.value.from.ldap": [ "true" ],
|
||||
"read.only": [ "true" ],
|
||||
"user.model.attribute": [ "modifyTimestamp" ]
|
||||
}
|
||||
},
|
||||
|
||||
{# ---------------------- LDAP Groups -> KC Groups -------- #}
|
||||
{
|
||||
"name": "ldap-roles",
|
||||
"providerId": "group-ldap-mapper",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"membership.attribute.type": [ "DN" ],
|
||||
"group.name.ldap.attribute": [ "cn" ],
|
||||
"membership.user.ldap.attribute": [ "{{ ldap.user.attributes.id }}" ],
|
||||
"preserve.group.inheritance": [ "true" ],
|
||||
"groups.dn": [ "{{ ldap.dn.ou.roles }}" ],
|
||||
"mode": [ "LDAP_ONLY" ],
|
||||
"user.roles.retrieve.strategy": [ "LOAD_GROUPS_BY_MEMBER_ATTRIBUTE" ],
|
||||
"groups.ldap.filter": [
|
||||
"{% set flavors = ldap.rbac.flavors | default([]) %}\
|
||||
{% if 'groupOfNames' in flavors and 'organizationalUnit' in flavors %}(|(objectClass=groupOfNames)(objectClass=organizationalUnit))\
|
||||
{% elif 'groupOfNames' in flavors %}(objectClass=groupOfNames)\
|
||||
{% elif 'organizationalUnit' in flavors %}(objectClass=organizationalUnit)\
|
||||
{% else %}(objectClass=groupOfNames){% endif %}"
|
||||
],
|
||||
"membership.ldap.attribute": [ "member" ],
|
||||
"ignore.missing.groups": [ "true" ],
|
||||
"group.object.classes": [ "groupOfNames" ],
|
||||
"memberof.ldap.attribute": [ "memberOf" ],
|
||||
"drop.non.existing.groups.during.sync": [ "false" ],
|
||||
"groups.path": [ "{{ applications | get_app_conf(application_id, 'rbac_groups', True) }}" ]
|
||||
}
|
||||
}{% if keycloak_map_ldap_realm_roles | default(false) %},
|
||||
{# ---------------------- LDAP -> Realm Roles (optional) -- #}
|
||||
{
|
||||
"name": "ldap-realm-roles",
|
||||
"providerId": "role-ldap-mapper",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"mode": [ "LDAP_ONLY" ],
|
||||
"membership.attribute.type": [ "DN" ],
|
||||
"user.roles.retrieve.strategy": [ "LOAD_ROLES_BY_MEMBER_ATTRIBUTE" ],
|
||||
"roles.dn": [ "{{ ldap.dn.ou.roles }}" ],
|
||||
"membership.ldap.attribute": [ "member" ],
|
||||
"membership.user.ldap.attribute": [ "{{ ldap.user.attributes.id }}" ],
|
||||
"memberof.ldap.attribute": [ "memberOf" ],
|
||||
"role.name.ldap.attribute": [ "cn" ],
|
||||
"use.realm.roles.mapping": [ "true" ],
|
||||
"role.object.classes": [ "groupOfNames" ]
|
||||
}
|
||||
}{% endif %}
|
||||
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"fullSyncPeriod": [ "-1" ],
|
||||
"pagination": [ "true" ],
|
||||
"connectionTrace": [ "false" ],
|
||||
"startTls": [ "false" ],
|
||||
"usersDn": [ "{{ ldap.dn.ou.users }}" ],
|
||||
"connectionPooling": [ "true" ],
|
||||
"cachePolicy": [ "DEFAULT" ],
|
||||
"useKerberosForPasswordAuthentication": [ "false" ],
|
||||
"importEnabled": [ "true" ],
|
||||
"enabled": [ "true" ],
|
||||
"bindCredential": [ "{{ KEYCLOAK_LDAP_BIND_PW }}" ],
|
||||
"changedSyncPeriod": [ "-1" ],
|
||||
"usernameLDAPAttribute": [ "{{ ldap.user.attributes.id }}" ],
|
||||
"bindDn": [ "{{ KEYCLOAK_LDAP_BIND_DN }}" ],
|
||||
"vendor": [ "other" ],
|
||||
"uuidLDAPAttribute": [ "{{ ldap.user.attributes.id }}" ],
|
||||
"allowKerberosAuthentication": [ "false" ],
|
||||
"connectionUrl": [ "{{ KEYCLOAK_LDAP_URL }}" ],
|
||||
"syncRegistrations": [ "true" ],
|
||||
"authType": [ "simple" ],
|
||||
"krbPrincipalAttribute": [ "krb5PrincipalName" ],
|
||||
"searchScope": [ "1" ],
|
||||
"useTruststoreSpi": [ "always" ],
|
||||
"usePasswordModifyExtendedOp": [ "true" ],
|
||||
"trustEmail": [ "false" ],
|
||||
|
||||
{# Build objectClasses from structural + auxiliary definitions #}
|
||||
"userObjectClasses": [
|
||||
"{{ (ldap.user.objects.structural + (ldap.user.objects.auxiliary | dict2items | map(attribute='value') | list)) | join(', ') }}"
|
||||
],
|
||||
|
||||
"rdnLDAPAttribute": [ "{{ ldap.user.attributes.id }}" ],
|
||||
"editMode": [ "WRITABLE" ],
|
||||
"validatePasswordPolicy": [ "false" ],
|
||||
|
||||
{# Recommended: prune Keycloak shadow users not in LDAP anymore #}
|
||||
"removeInvalidUsersEnabled": [ "true" ]
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -3,24 +3,63 @@ application_id: "web-app-keycloak"
|
||||
database_type: "postgres" # Database which will be used
|
||||
|
||||
# Keycloak
|
||||
keycloak_container: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.name') }}" # Name of the keycloak docker container
|
||||
keycloak_docker_import_directory: "/opt/keycloak/data/import/" # Directory in which keycloak import files are placed in the running docker container
|
||||
keycloak_realm: "{{ OIDC.CLIENT.REALM }}" # This is the name of the default realm which is used by the applications
|
||||
keycloak_master_api_user: "{{ applications | get_app_conf(application_id, 'users.administrator') }}" # Master Administrator
|
||||
keycloak_master_api_user_name: "{{ keycloak_master_api_user.username }}" # Master Administrator Username
|
||||
keycloak_master_api_user_password: "{{ keycloak_master_api_user.password }}" # Master Administrator Password
|
||||
keycloak_kcadm_path: "docker exec -i {{ keycloak_container }} /opt/keycloak/bin/kcadm.sh" # Init script for keycloak
|
||||
keycloak_server_internal_url: "http://127.0.0.1:8080"
|
||||
keycloak_server_host: "127.0.0.1:{{ ports.localhost.http[application_id] }}"
|
||||
keycloak_server_host_url: "http://{{ keycloak_server_host }}"
|
||||
keycloak_image: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.image') }}" # Keycloak docker image
|
||||
keycloak_version: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.version') }}" # Keycloak docker version
|
||||
keycloak_debug_enabled: "{{ MODE_DEBUG }}"
|
||||
keycloak_redirect_features: ["features.oauth2","features.oidc"]
|
||||
keycloak_client_id: "{{ OIDC.CLIENT.ID }}"
|
||||
keycloak_ldap_component_name: "{{ ldap.server.domain }}" # Name of the LDAP User Federation component in Keycloak (as shown in UI)
|
||||
keycloak_import_realm: "{{ applications | get_app_conf(application_id, 'actions.import_realm') }}" # Activate realm import
|
||||
keycloak_update_ldap_bind: "{{ applications | get_app_conf(application_id, 'actions.update_ldap_bind') }}" # Toggle the LDAP bind update step
|
||||
|
||||
# Docker
|
||||
docker_compose_flush_handlers: true # Remember to copy realm import before flush when set to true
|
||||
## General
|
||||
KEYCLOAK_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
|
||||
KEYCLOAK_REALM: "{{ OIDC.CLIENT.REALM }}" # This is the name of the default realm which is used by the applications
|
||||
KEYCLOAK_REALM_URL: "{{ WEB_PROTOCOL }}://{{ KEYCLOAK_REALM }}"
|
||||
KEYCLOAK_DEBUG_ENABLED: "{{ MODE_DEBUG }}"
|
||||
KEYCLOAK_CLIENT_ID: "{{ OIDC.CLIENT.ID }}"
|
||||
KEYCLOAK_MASTER_REALM_URL: "{{ KEYCLOAK_SERVER_HOST_URL }}/realms/master"
|
||||
KEYCLOAK_HOST_IMPORT_DIR: "{{ docker_compose.directories.volumes }}import/"
|
||||
KEYCLOAK_SERVER_INTERNAL_URL: "http://127.0.0.1:8080"
|
||||
|
||||
# Credentials
|
||||
KEYCLOAK_ADMIN: "{{ applications | get_app_conf(application_id, 'users.administrator.username') }}"
|
||||
KEYCLOAK_ADMIN_PASSWORD: "{{ applications | get_app_conf(application_id, 'credentials.administrator_password') }}"
|
||||
|
||||
## Docker
|
||||
KEYCLOAK_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.name') }}" # Name of the keycloak docker container
|
||||
KEYCLOAK_DOCKER_IMPORT_DIR: "/opt/keycloak/data/import/" # Directory in which keycloak import files are placed in the running docker container
|
||||
KEYCLOAK_EXEC_KCADM: "docker exec -i {{ KEYCLOAK_CONTAINER }} /opt/keycloak/bin/kcadm.sh" # Init script for keycloak
|
||||
KEYCLOAK_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.image') }}" # Keycloak docker image
|
||||
KEYCLOAK_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.version') }}" # Keycloak docker version
|
||||
|
||||
## Server
|
||||
KEYCLOAK_SERVER_HOST: "127.0.0.1:{{ ports.localhost.http[application_id] }}"
|
||||
KEYCLOAK_SERVER_HOST_URL: "http://{{ KEYCLOAK_SERVER_HOST }}"
|
||||
|
||||
## Update
|
||||
KEYCLOAK_REDIRECT_FEATURES: ["features.oauth2","features.oidc"]
|
||||
KEYCLOAK_IMPORT_REALM_ENABLED: "{{ applications | get_app_conf(application_id, 'actions.import_realm') }}" # Activate realm import
|
||||
KEYCLOAK_FRONTCHANNEL_LOGOUT_URL: "{{ domains | get_url('web-svc-logout', WEB_PROTOCOL) }}/"
|
||||
KEYCLOAK_REDIRECT_URIS: "{{ domains | redirect_uris(applications, WEB_PROTOCOL, '/*', KEYCLOAK_REDIRECT_FEATURES) }}"
|
||||
KEYCLOAK_WEB_ORIGINS: >-
|
||||
{{ KEYCLOAK_REDIRECT_URIS
|
||||
| map('regex_replace','/\\*$','')
|
||||
| map('regex_search','^(https?://[^/]+)')
|
||||
| select('string')
|
||||
| list | unique }}
|
||||
KEYCLOAK_POST_LOGOUT_URIS: "+"
|
||||
|
||||
## LDAP
|
||||
KEYCLOAK_LDAP_ENABLED: "{{ applications | get_app_conf(application_id, 'features.ldap', False) }}"
|
||||
KEYCLOAK_LDAP_CMP_NAME: "{{ ldap.server.domain }}" # Name of the LDAP User Federation component in Keycloak (as shown in UI)
|
||||
KEYCLOAK_LDAP_BIND_DN: "{{ ldap.dn.administrator.data }}"
|
||||
KEYCLOAK_LDAP_BIND_PW: "{{ ldap.bind_credential }}"
|
||||
KEYCLOAK_LDAP_URL: "{{ ldap.server.uri }}"
|
||||
|
||||
## API
|
||||
KEYCLOAK_MASTER_API_USER: "{{ applications | get_app_conf(application_id, 'users.administrator') }}" # Master Administrator
|
||||
KEYCLOAK_MASTER_API_USER_NAME: "{{ KEYCLOAK_MASTER_API_USER.username }}" # Master Administrator Username
|
||||
KEYCLOAK_MASTER_API_USER_PASSWORD: "{{ KEYCLOAK_MASTER_API_USER.password }}" # Master Administrator Password
|
||||
|
||||
|
||||
# Dictionaries
|
||||
KEYCLOAK_DICTIONARY_REALM_RAW: "{{ lookup('template', 'import/realm.json.j2') }}"
|
||||
KEYCLOAK_DICTIONARY_REALM: >-
|
||||
{{
|
||||
KEYCLOAK_DICTIONARY_REALM_RAW
|
||||
if (KEYCLOAK_DICTIONARY_REALM_RAW is mapping)
|
||||
else (KEYCLOAK_DICTIONARY_REALM_RAW | from_json)
|
||||
}}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
# https://github.com/LDAPAccountManager/lam/blob/develop/lam-packaging/docker/.env
|
||||
|
||||
# Basic Configuration
|
||||
LAM_PASSWORD= {{applications | get_app_conf(application_id, 'credentials.administrator_password', True)}} # LAM configuration master password and password for server profile "lam
|
||||
LAM_PASSWORD= {{ applications | get_app_conf(application_id, 'credentials.administrator_password') }} # LAM configuration master password and password for server profile "lam
|
||||
|
||||
# Database
|
||||
LAM_CONFIGURATION_DATABASE= files # configuration database (files or mysql) @todo implement mariadb
|
||||
|
@@ -2,5 +2,5 @@ TZ={{ HOST_TIMEZONE }}
|
||||
|
||||
# Administrator setup
|
||||
|
||||
LISTMONK_ADMIN_USER={{ applications | get_app_conf(application_id, 'users.administrator.username', True) }}
|
||||
LISTMONK_ADMIN_USER={{ applications | get_app_conf(application_id, 'users.administrator.username') }}
|
||||
LISTMONK_ADMIN_PASSWORD={{ applications | get_app_conf(application_id, 'credentials.administrator_password', True) }}
|
@@ -103,7 +103,7 @@
|
||||
|
||||
- name: create admin account
|
||||
command:
|
||||
cmd: docker compose exec -it synapse register_new_matrix_user -u {{ MATRIX_ADMINISTRATOR_USERNAME }} -p {{applications | get_app_conf(application_id, 'credentials.administrator_password', True)}} -a -c {{ MATRIX_SYNAPSE_CONFIG_PATH_CONTAINER }} http://localhost:8008
|
||||
cmd: docker compose exec -it synapse register_new_matrix_user -u {{ MATRIX_ADMINISTRATOR_USERNAME }} -p {{ applications | get_app_conf(application_id, 'credentials.administrator_password') }} -a -c {{ MATRIX_SYNAPSE_CONFIG_PATH_CONTAINER }} http://localhost:8008
|
||||
chdir: "{{ docker_compose.directories.instance }}"
|
||||
ignore_errors: true
|
||||
when: applications | get_app_conf(application_id, 'setup', True) | bool
|
||||
|
@@ -4,7 +4,7 @@ MOODLE_SITE_NAME="{{applications | get_app_conf(application_id, 'site_titel', Tr
|
||||
MOODLE_HOST="{{ domains | get_domain(application_id) }}"
|
||||
MOODLE_SSLPROXY=yes
|
||||
MOODLE_REVERSE_PROXY=yes
|
||||
MOODLE_USERNAME={{applications | get_app_conf(application_id, 'users.administrator.username', True)}}
|
||||
MOODLE_USERNAME={{ applications | get_app_conf(application_id, 'users.administrator.username') }}
|
||||
MOODLE_PASSWORD={{applications | get_app_conf(application_id, 'credentials.user_password', True)}}
|
||||
MOODLE_EMAIL={{applications | get_app_conf(application_id, 'users.administrator.email', True)}}
|
||||
BITNAMI_DEBUG={% if MODE_DEBUG | bool %}true{% else %}false{% endif %}
|
||||
|
@@ -12,7 +12,7 @@ database_password: "{{ applications | get_app_conf(
|
||||
database_type: "mariadb" # Database flavor
|
||||
|
||||
nextcloud_plugins_enabled: "{{ applications | get_app_conf(application_id, 'plugins_enabled', True) }}"
|
||||
nextcloud_administrator_username: "{{ applications | get_app_conf(application_id, 'users.administrator.username', True) }}"
|
||||
nextcloud_administrator_username: "{{ applications | get_app_conf(application_id, 'users.administrator.username') }}"
|
||||
|
||||
# Control Node
|
||||
nextcloud_control_node_plugin_vars_directory: "{{role_path}}/vars/plugins/" # Folder in which the files for the plugin configuration are stored
|
||||
|
@@ -5,7 +5,7 @@
|
||||
wp core install
|
||||
--url="{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
|
||||
--title="{{ applications | get_app_conf(application_id, 'title', True) }}"
|
||||
--admin_user="{{ applications | get_app_conf(application_id, 'users.administrator.username', True) }}"
|
||||
--admin_user="{{ applications | get_app_conf(application_id, 'users.administrator.username') }}"
|
||||
--admin_password="{{ applications | get_app_conf(application_id, 'credentials.administrator_password', True) }}"
|
||||
--admin_email="{{ applications | get_app_conf(application_id, 'users.administrator.email', True) }}"
|
||||
--path="{{ wordpress_docker_html_path }}"
|
||||
|
@@ -3,7 +3,7 @@ application_id: "web-app-yourls"
|
||||
database_type: "mariadb"
|
||||
|
||||
# Yourls Specific
|
||||
yourls_user: "{{ applications | get_app_conf(application_id, 'users.administrator.username', True) }}"
|
||||
yourls_user: "{{ applications | get_app_conf(application_id, 'users.administrator.username') }}"
|
||||
yourls_password: "{{ applications | get_app_conf(application_id, 'credentials.administrator_password', True) }}"
|
||||
yourls_version: "{{ applications | get_app_conf(application_id, 'docker.services.yourls.version', True) }}"
|
||||
yourls_image: "{{ applications | get_app_conf(application_id, 'docker.services.yourls.image', True) }}"
|
||||
|
Reference in New Issue
Block a user