mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-11-21 04:26:39 +00:00
Compare commits
14 Commits
feature/ke
...
0b86b2f057
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b86b2f057 | |||
| 80e048a274 | |||
| 2610aec293 | |||
| 07db162368 | |||
| a526d1adc4 | |||
| ca95079111 | |||
| e410d66cb4 | |||
| ab48cf522f | |||
| 41c12bdc12 | |||
| aae463b602 | |||
| bb50551533 | |||
| 098099b41e | |||
| 0a7d767252 | |||
| d88599f76c |
@@ -5,6 +5,6 @@ MODE_DUMMY: false # Executes dummy/test routines instead
|
|||||||
MODE_UPDATE: true # Executes updates
|
MODE_UPDATE: true # Executes updates
|
||||||
MODE_DEBUG: false # This enables debugging in ansible and in the apps, You SHOULD NOT enable this on production servers
|
MODE_DEBUG: false # This enables debugging in ansible and in the apps, You SHOULD NOT enable this on production servers
|
||||||
MODE_RESET: false # Cleans up all Infinito.Nexus files. It's necessary to run to whole playbook and not particial roles when using this function.
|
MODE_RESET: false # Cleans up all Infinito.Nexus files. It's necessary to run to whole playbook and not particial roles when using this function.
|
||||||
MODE_CLEANUP: "{{ MODE_DEBUG | bool }}" # Cleanup unused files and configurations
|
MODE_CLEANUP: true # Cleanup unused files and configurations
|
||||||
MODE_ASSERT: "{{ MODE_DEBUG | bool }}" # Executes validation tasks during the run.
|
MODE_ASSERT: "{{ MODE_DEBUG | bool }}" # Executes validation tasks during the run.
|
||||||
MODE_BACKUP: true # Executes the Backup before the deployment
|
MODE_BACKUP: true # Executes the Backup before the deployment
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ users:
|
|||||||
username: "{{ PRIMARY_DOMAIN.split('.')[0] }}"
|
username: "{{ PRIMARY_DOMAIN.split('.')[0] }}"
|
||||||
tld:
|
tld:
|
||||||
description: "Auto Generated Account to reserve the TLD"
|
description: "Auto Generated Account to reserve the TLD"
|
||||||
username: "{{ PRIMARY_DOMAIN.split('.')[1] }}"
|
username: "{{ PRIMARY_DOMAIN.split('.')[1] if (PRIMARY_DOMAIN is defined and (PRIMARY_DOMAIN.split('.') | length) > 1) else (PRIMARY_DOMAIN ~ '_tld ') }}"
|
||||||
root:
|
root:
|
||||||
username: root
|
username: root
|
||||||
uid: 0
|
uid: 0
|
||||||
|
|||||||
@@ -43,9 +43,10 @@ plugins:
|
|||||||
enabled: true
|
enabled: true
|
||||||
discourse-akismet:
|
discourse-akismet:
|
||||||
enabled: true
|
enabled: true
|
||||||
discourse-cakeday:
|
# The following plugins moved to the default setup
|
||||||
enabled: true
|
# discourse-cakeday:
|
||||||
# discourse-solved: Seems like this plugin is now also part of the default setup
|
# enabled: true
|
||||||
|
# discourse-solved:
|
||||||
# enabled: true
|
# enabled: true
|
||||||
# discourse-voting:
|
# discourse-voting:
|
||||||
# enabled: true
|
# enabled: true
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -euo pipefail
|
# POSIX-safe entrypoint for EspoCRM container
|
||||||
|
# Compatible with /bin/sh (dash/busybox). Avoids 'pipefail' and non-portable features.
|
||||||
|
set -eu
|
||||||
|
|
||||||
log() { printf '%s %s\n' "[entrypoint]" "$*" >&2; }
|
log() { printf '%s %s\n' "[entrypoint]" "$*" >&2; }
|
||||||
|
|
||||||
# --- Simple boolean normalization --------------------------------------------
|
# --- Simple boolean normalization --------------------------------------------
|
||||||
bool_norm () {
|
bool_norm () {
|
||||||
v="$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')"
|
v="$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]' 2>/dev/null || true)"
|
||||||
case "$v" in
|
case "$v" in
|
||||||
1|true|yes|on) echo "true" ;;
|
1|true|yes|on) echo "true" ;;
|
||||||
0|false|no|off|"") echo "false" ;;
|
0|false|no|off|"") echo "false" ;;
|
||||||
@@ -13,30 +15,45 @@ bool_norm () {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
# Expected ENV (from env.j2)
|
# --- Environment initialization ----------------------------------------------
|
||||||
MAINTENANCE="$(bool_norm "${ESPO_INIT_MAINTENANCE_MODE:-false}")"
|
MAINTENANCE="$(bool_norm "${ESPO_INIT_MAINTENANCE_MODE:-false}")"
|
||||||
CRON_DISABLED="$(bool_norm "${ESPO_INIT_CRON_DISABLED:-false}")"
|
CRON_DISABLED="$(bool_norm "${ESPO_INIT_CRON_DISABLED:-false}")"
|
||||||
USE_CACHE="$(bool_norm "${ESPO_INIT_USE_CACHE:-true}")"
|
USE_CACHE="$(bool_norm "${ESPO_INIT_USE_CACHE:-true}")"
|
||||||
|
|
||||||
APP_DIR="/var/www/html"
|
APP_DIR="/var/www/html"
|
||||||
SET_FLAGS_SCRIPT="${ESPOCRM_SET_FLAGS_SCRIPT}"
|
|
||||||
|
# Provided by env.j2 (fallback ensures robustness)
|
||||||
|
SET_FLAGS_SCRIPT="${ESPOCRM_SET_FLAGS_SCRIPT:-/usr/local/bin/set_flags.php}"
|
||||||
|
if [ ! -f "$SET_FLAGS_SCRIPT" ]; then
|
||||||
|
log "WARN: SET_FLAGS_SCRIPT '$SET_FLAGS_SCRIPT' not found; falling back to /usr/local/bin/set_flags.php"
|
||||||
|
SET_FLAGS_SCRIPT="/usr/local/bin/set_flags.php"
|
||||||
|
fi
|
||||||
|
|
||||||
# --- Wait for bootstrap.php (max 60s, e.g. fresh volume) ----------------------
|
# --- Wait for bootstrap.php (max 60s, e.g. fresh volume) ----------------------
|
||||||
log "Waiting for ${APP_DIR}/bootstrap.php..."
|
log "Waiting for ${APP_DIR}/bootstrap.php..."
|
||||||
for i in $(seq 1 60); do
|
count=0
|
||||||
[ -f "${APP_DIR}/bootstrap.php" ] && break
|
while [ $count -lt 60 ] && [ ! -f "${APP_DIR}/bootstrap.php" ]; do
|
||||||
sleep 1
|
sleep 1
|
||||||
|
count=$((count + 1))
|
||||||
done
|
done
|
||||||
if [ ! -f "${APP_DIR}/bootstrap.php" ]; then
|
if [ ! -f "${APP_DIR}/bootstrap.php" ]; then
|
||||||
log "ERROR: bootstrap.php missing after 60s"; exit 1
|
log "ERROR: bootstrap.php missing after 60s"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Apply config flags via set_flags.php ------------------------------------
|
# --- Apply config flags via set_flags.php ------------------------------------
|
||||||
log "Applying runtime flags via set_flags.php..."
|
log "Applying runtime flags via set_flags.php..."
|
||||||
php "${SET_FLAGS_SCRIPT}"
|
if ! php "${SET_FLAGS_SCRIPT}"; then
|
||||||
|
log "ERROR: set_flags.php execution failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# --- Clear cache (safe) -------------------------------------------------------
|
# --- Clear cache (safe) -------------------------------------------------------
|
||||||
php "${APP_DIR}/clear_cache.php" || true
|
if php "${APP_DIR}/clear_cache.php" 2>/dev/null; then
|
||||||
|
log "Cache cleared successfully."
|
||||||
|
else
|
||||||
|
log "WARN: Cache clearing skipped or failed (non-critical)."
|
||||||
|
fi
|
||||||
|
|
||||||
# --- Hand off to CMD ----------------------------------------------------------
|
# --- Hand off to CMD ----------------------------------------------------------
|
||||||
if [ "$#" -gt 0 ]; then
|
if [ "$#" -gt 0 ]; then
|
||||||
@@ -56,5 +73,6 @@ for cmd in apache2-foreground httpd-foreground php-fpm php-fpm8.3 php-fpm8.2 sup
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# --- Fallback ---------------------------------------------------------------
|
||||||
log "No known server command found; tailing to keep container alive."
|
log "No known server command found; tailing to keep container alive."
|
||||||
exec tail -f /dev/null
|
exec tail -f /dev/null
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
load_dependencies: True # When set to false the dependencies aren't loaded. Helpful for developing
|
load_dependencies: True # When set to false the dependencies aren't loaded. Helpful for developing
|
||||||
actions:
|
actions:
|
||||||
import_realm: True # Import REALM
|
import_realm: True # Import REALM
|
||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: true
|
css: true
|
||||||
@@ -49,4 +49,10 @@ docker:
|
|||||||
credentials:
|
credentials:
|
||||||
recaptcha:
|
recaptcha:
|
||||||
website_key: "" # Required if you enabled recaptcha:
|
website_key: "" # Required if you enabled recaptcha:
|
||||||
secret_key: "" # Required if you enabled recaptcha:
|
secret_key: "" # Required if you enabled recaptcha:
|
||||||
|
|
||||||
|
accounts:
|
||||||
|
bootstrap:
|
||||||
|
username: "administrator"
|
||||||
|
system:
|
||||||
|
username: "{{ SOFTWARE_NAME | replace('.', '_') | lower }}"
|
||||||
89
roles/web-app-keycloak/tasks/05_login.yml
Normal file
89
roles/web-app-keycloak/tasks/05_login.yml
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
- name: "Wait until '{{ KEYCLOAK_CONTAINER }}' container is healthy"
|
||||||
|
community.docker.docker_container_info:
|
||||||
|
name: "{{ KEYCLOAK_CONTAINER }}"
|
||||||
|
register: kc_info
|
||||||
|
retries: 60
|
||||||
|
delay: 5
|
||||||
|
until: >
|
||||||
|
kc_info is succeeded and
|
||||||
|
(kc_info.container | default({})) != {} and
|
||||||
|
(kc_info.container.State | default({})) != {} and
|
||||||
|
(kc_info.container.State.Health | default({})) != {} and
|
||||||
|
(kc_info.container.State.Health.Status | default('')) == 'healthy'
|
||||||
|
|
||||||
|
- name: Ensure permanent Keycloak admin exists and can log in (container env only)
|
||||||
|
block:
|
||||||
|
|
||||||
|
- name: Try login with permanent admin (uses container ENV)
|
||||||
|
shell: |
|
||||||
|
{{ KEYCLOAK_EXEC_CONTAINER }} sh -lc '
|
||||||
|
{{ KEYCLOAK_KCADM }} config credentials \
|
||||||
|
--server {{ KEYCLOAK_SERVER_INTERNAL_URL }} \
|
||||||
|
--realm master \
|
||||||
|
--user "$KEYCLOAK_PERMANENT_ADMIN_USERNAME" \
|
||||||
|
--password "$KEYCLOAK_PERMANENT_ADMIN_PASSWORD"
|
||||||
|
'
|
||||||
|
register: kc_login_perm
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
rescue:
|
||||||
|
|
||||||
|
- name: Login with bootstrap admin (uses container ENV)
|
||||||
|
shell: |
|
||||||
|
{{ KEYCLOAK_EXEC_CONTAINER }} sh -lc '
|
||||||
|
{{ KEYCLOAK_KCADM }} config credentials \
|
||||||
|
--server {{ KEYCLOAK_SERVER_INTERNAL_URL }} \
|
||||||
|
--realm master \
|
||||||
|
--user "$KC_BOOTSTRAP_ADMIN_USERNAME" \
|
||||||
|
--password "$KC_BOOTSTRAP_ADMIN_PASSWORD"
|
||||||
|
'
|
||||||
|
register: kc_login_bootstrap
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Ensure permanent admin user exists (create if missing)
|
||||||
|
shell: |
|
||||||
|
{{ KEYCLOAK_EXEC_CONTAINER }} sh -lc '
|
||||||
|
{{ KEYCLOAK_KCADM }} create users -r master \
|
||||||
|
-s "username=$KEYCLOAK_PERMANENT_ADMIN_USERNAME" \
|
||||||
|
-s "enabled=true"
|
||||||
|
'
|
||||||
|
register: kc_create_perm_admin
|
||||||
|
failed_when: >
|
||||||
|
not (
|
||||||
|
kc_create_perm_admin.rc == 0 or
|
||||||
|
(kc_create_perm_admin.stderr is defined and
|
||||||
|
('User exists with same username' in kc_create_perm_admin.stderr))
|
||||||
|
)
|
||||||
|
changed_when: kc_create_perm_admin.rc == 0
|
||||||
|
|
||||||
|
- name: Set permanent admin password (by username, no ID needed)
|
||||||
|
shell: |
|
||||||
|
{{ KEYCLOAK_EXEC_CONTAINER }} sh -lc '
|
||||||
|
{{ KEYCLOAK_KCADM }} set-password -r master \
|
||||||
|
--username "$KEYCLOAK_PERMANENT_ADMIN_USERNAME" \
|
||||||
|
--new-password "$KEYCLOAK_PERMANENT_ADMIN_PASSWORD"
|
||||||
|
'
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
|
- name: Grant global admin via master realm role 'admin'
|
||||||
|
shell: |
|
||||||
|
{{ KEYCLOAK_EXEC_CONTAINER }} sh -lc '
|
||||||
|
{{ KEYCLOAK_KCADM }} add-roles -r master \
|
||||||
|
--uusername "$KEYCLOAK_PERMANENT_ADMIN_USERNAME" \
|
||||||
|
--rolename admin
|
||||||
|
'
|
||||||
|
register: kc_grant_master_admin
|
||||||
|
changed_when: (kc_grant_master_admin.stderr is defined and kc_grant_master_admin.stderr | length > 0) or
|
||||||
|
(kc_grant_master_admin.stdout is defined and kc_grant_master_admin.stdout | length > 0)
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Verify login with permanent admin (after creation)
|
||||||
|
shell: |
|
||||||
|
{{ KEYCLOAK_EXEC_CONTAINER }} sh -lc '
|
||||||
|
{{ KEYCLOAK_KCADM }} config credentials \
|
||||||
|
--server {{ KEYCLOAK_SERVER_INTERNAL_URL }} \
|
||||||
|
--realm master \
|
||||||
|
--user "$KEYCLOAK_PERMANENT_ADMIN_USERNAME" \
|
||||||
|
--password "$KEYCLOAK_PERMANENT_ADMIN_PASSWORD"
|
||||||
|
'
|
||||||
|
changed_when: false
|
||||||
@@ -13,82 +13,21 @@
|
|||||||
include_tasks: 04_dependencies.yml
|
include_tasks: 04_dependencies.yml
|
||||||
when: KEYCLOAK_LOAD_DEPENDENCIES | bool
|
when: KEYCLOAK_LOAD_DEPENDENCIES | bool
|
||||||
|
|
||||||
- name: "Wait until '{{ KEYCLOAK_CONTAINER }}' container is healthy"
|
- name: "Load Login routines for '{{ application_id }}'"
|
||||||
community.docker.docker_container_info:
|
include_tasks: 05_login.yml
|
||||||
name: "{{ KEYCLOAK_CONTAINER }}"
|
|
||||||
register: kc_info
|
|
||||||
retries: 60
|
|
||||||
delay: 5
|
|
||||||
until: >
|
|
||||||
kc_info is succeeded and
|
|
||||||
(kc_info.container | default({})) != {} and
|
|
||||||
(kc_info.container.State | default({})) != {} and
|
|
||||||
(kc_info.container.State.Health | default({})) != {} and
|
|
||||||
(kc_info.container.State.Health.Status | default('')) == 'healthy'
|
|
||||||
|
|
||||||
- name: kcadm login (master)
|
- name: "Load Client Update routines for '{{ application_id }}'"
|
||||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
include_tasks: update/01_client.yml
|
||||||
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 Client settings"
|
- name: "Load Mail Update routines for '{{ application_id }} - {{ KEYCLOAK_REALM }}'"
|
||||||
vars:
|
include_tasks: update/02_mail_realm.yml
|
||||||
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:
|
|
||||||
publicClient: >-
|
|
||||||
{{
|
|
||||||
(KEYCLOAK_DICTIONARY_REALM.clients
|
|
||||||
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
||||||
| map(attribute='publicClient')
|
|
||||||
| first)
|
|
||||||
}}
|
|
||||||
serviceAccountsEnabled: >-
|
|
||||||
{{
|
|
||||||
(KEYCLOAK_DICTIONARY_REALM.clients
|
|
||||||
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
||||||
| map(attribute='serviceAccountsEnabled')
|
|
||||||
| first )
|
|
||||||
}}
|
|
||||||
frontchannelLogout: >-
|
|
||||||
{{
|
|
||||||
(KEYCLOAK_DICTIONARY_REALM.clients
|
|
||||||
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
||||||
| map(attribute='frontchannelLogout')
|
|
||||||
| first)
|
|
||||||
}}
|
|
||||||
attributes: >-
|
|
||||||
{{
|
|
||||||
( (KEYCLOAK_DICTIONARY_REALM.clients
|
|
||||||
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
||||||
| list | first | default({}) ).attributes | default({}) )
|
|
||||||
| combine({'frontchannel.logout.url': KEYCLOAK_FRONTCHANNEL_LOGOUT_URL}, recursive=True)
|
|
||||||
}}
|
|
||||||
include_tasks: _update.yml
|
|
||||||
|
|
||||||
- name: "Update REALM mail settings from realm dictionary (SPOT)"
|
- name: "Load Mail Update routines for '{{ application_id }} - master'"
|
||||||
include_tasks: _update.yml
|
include_tasks: update/03_mail_master.yml
|
||||||
vars:
|
|
||||||
kc_object_kind: "realm"
|
|
||||||
kc_lookup_field: "id"
|
|
||||||
kc_lookup_value: "{{ KEYCLOAK_REALM }}"
|
|
||||||
kc_desired:
|
|
||||||
smtpServer: "{{ KEYCLOAK_DICTIONARY_REALM.smtpServer | default({}, true) }}"
|
|
||||||
kc_merge_path: "smtpServer"
|
|
||||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
|
||||||
|
|
||||||
- include_tasks: 05_rbac_client_scope.yml
|
- name: "Load RBAC Update routines for '{{ application_id }}'"
|
||||||
|
include_tasks: update/04_rbac_client_scope.yml
|
||||||
|
|
||||||
- include_tasks: 06_ldap.yml
|
- name: "Load LDAP Update routines for '{{ application_id }}'"
|
||||||
|
include_tasks: update/05_ldap.yml
|
||||||
when: KEYCLOAK_LDAP_ENABLED | bool
|
when: KEYCLOAK_LDAP_ENABLED | bool
|
||||||
|
|||||||
40
roles/web-app-keycloak/tasks/update/01_client.yml
Normal file
40
roles/web-app-keycloak/tasks/update/01_client.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
- 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:
|
||||||
|
publicClient: >-
|
||||||
|
{{
|
||||||
|
(KEYCLOAK_DICTIONARY_REALM.clients
|
||||||
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
||||||
|
| map(attribute='publicClient')
|
||||||
|
| first)
|
||||||
|
}}
|
||||||
|
serviceAccountsEnabled: >-
|
||||||
|
{{
|
||||||
|
(KEYCLOAK_DICTIONARY_REALM.clients
|
||||||
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
||||||
|
| map(attribute='serviceAccountsEnabled')
|
||||||
|
| first )
|
||||||
|
}}
|
||||||
|
frontchannelLogout: >-
|
||||||
|
{{
|
||||||
|
(KEYCLOAK_DICTIONARY_REALM.clients
|
||||||
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
||||||
|
| map(attribute='frontchannelLogout')
|
||||||
|
| first)
|
||||||
|
}}
|
||||||
|
attributes: >-
|
||||||
|
{{
|
||||||
|
( (KEYCLOAK_DICTIONARY_REALM.clients
|
||||||
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
||||||
|
| list | first | default({}) ).attributes | default({}) )
|
||||||
|
| combine({'frontchannel.logout.url': KEYCLOAK_FRONTCHANNEL_LOGOUT_URL}, recursive=True)
|
||||||
|
}}
|
||||||
|
include_tasks: _update.yml
|
||||||
10
roles/web-app-keycloak/tasks/update/02_mail_realm.yml
Normal file
10
roles/web-app-keycloak/tasks/update/02_mail_realm.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
- name: "Update {{ KEYCLOAK_REALM }} REALM mail settings from realm dictionary"
|
||||||
|
include_tasks: _update.yml
|
||||||
|
vars:
|
||||||
|
kc_object_kind: "realm"
|
||||||
|
kc_lookup_field: "id"
|
||||||
|
kc_lookup_value: "{{ KEYCLOAK_REALM }}"
|
||||||
|
kc_desired:
|
||||||
|
smtpServer: "{{ KEYCLOAK_DICTIONARY_REALM.smtpServer | default({}, true) }}"
|
||||||
|
kc_merge_path: "smtpServer"
|
||||||
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||||
10
roles/web-app-keycloak/tasks/update/03_mail_master.yml
Normal file
10
roles/web-app-keycloak/tasks/update/03_mail_master.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
- name: "Update Master REALM mail settings from realm dictionary"
|
||||||
|
include_tasks: _update.yml
|
||||||
|
vars:
|
||||||
|
kc_object_kind: "realm"
|
||||||
|
kc_lookup_field: "id"
|
||||||
|
kc_lookup_value: "master"
|
||||||
|
kc_desired:
|
||||||
|
smtpServer: "{{ KEYCLOAK_DICTIONARY_REALM.smtpServer | default({}, true) }}"
|
||||||
|
kc_merge_path: "smtpServer"
|
||||||
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
# --- Ensure RBAC client scope exists (idempotent) ---
|
|
||||||
- name: Ensure RBAC client scope exists
|
- name: Ensure RBAC client scope exists
|
||||||
shell: |
|
shell: |
|
||||||
cat <<'JSON' | {{ KEYCLOAK_EXEC_KCADM }} create client-scopes -r {{ KEYCLOAK_REALM }} -f -
|
cat <<'JSON' | {{ KEYCLOAK_EXEC_KCADM }} create client-scopes -r {{ KEYCLOAK_REALM }} -f -
|
||||||
@@ -16,7 +15,6 @@
|
|||||||
('already exists' not in (create_rbac_scope.stderr | lower))
|
('already exists' not in (create_rbac_scope.stderr | lower))
|
||||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||||
|
|
||||||
# --- Get the scope id we will attach to the client ---
|
|
||||||
- name: Get all client scopes
|
- name: Get all client scopes
|
||||||
shell: "{{ KEYCLOAK_EXEC_KCADM }} get client-scopes -r {{ KEYCLOAK_REALM }} --format json"
|
shell: "{{ KEYCLOAK_EXEC_KCADM }} get client-scopes -r {{ KEYCLOAK_REALM }} --format json"
|
||||||
register: all_scopes
|
register: all_scopes
|
||||||
@@ -10,19 +10,21 @@ KC_HTTP_ENABLED= true
|
|||||||
KC_HEALTH_ENABLED= {{ KEYCLOAK_HEALTH_ENABLED | lower }}
|
KC_HEALTH_ENABLED= {{ KEYCLOAK_HEALTH_ENABLED | lower }}
|
||||||
KC_METRICS_ENABLED= true
|
KC_METRICS_ENABLED= true
|
||||||
|
|
||||||
# Administrator
|
|
||||||
KEYCLOAK_ADMIN= "{{ KEYCLOAK_ADMIN }}"
|
|
||||||
KEYCLOAK_ADMIN_PASSWORD= "{{ KEYCLOAK_ADMIN_PASSWORD }}"
|
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
KC_DB= {{ database_type }}
|
KC_DB= {{ database_type }}
|
||||||
KC_DB_URL= {{ database_url_jdbc }}
|
KC_DB_URL= {{ database_url_jdbc }}
|
||||||
KC_DB_USERNAME= {{ database_username }}
|
KC_DB_USERNAME= {{ database_username }}
|
||||||
KC_DB_PASSWORD= {{ database_password }}
|
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.
|
# Credentials
|
||||||
KC_BOOTSTRAP_ADMIN_USERNAME= "{{ KEYCLOAK_ADMIN }}"
|
|
||||||
KC_BOOTSTRAP_ADMIN_PASSWORD= "{{ KEYCLOAK_ADMIN_PASSWORD }}"
|
## Bootstrap
|
||||||
|
KC_BOOTSTRAP_ADMIN_USERNAME="{{ KEYCLOAK_BOOTSTRAP_ADMIN_USERNAME }}"
|
||||||
|
KC_BOOTSTRAP_ADMIN_PASSWORD="{{ KEYCLOAK_BOOTSTRAP_ADMIN_PASSWORD }}"
|
||||||
|
|
||||||
|
## Permanent
|
||||||
|
KEYCLOAK_PERMANENT_ADMIN_USERNAME="{{ KEYCLOAK_PERMANENT_ADMIN_USERNAME }}"
|
||||||
|
KEYCLOAK_PERMANENT_ADMIN_PASSWORD="{{ KEYCLOAK_PERMANENT_ADMIN_PASSWORD }}"
|
||||||
|
|
||||||
# Enable detailed logs
|
# Enable detailed logs
|
||||||
{% if MODE_DEBUG | bool %}
|
{% if MODE_DEBUG | bool %}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
users:
|
|
||||||
administrator:
|
|
||||||
username: "administrator"
|
|
||||||
@@ -29,14 +29,22 @@ KEYCLOAK_REALM_IMPORT_FILE_SRC: "import/realm.json.j2"
|
|||||||
KEYCLOAK_REALM_IMPORT_FILE_DST: "{{ [KEYCLOAK_REALM_IMPORT_DIR_HOST,'realm.json'] | path_join }}"
|
KEYCLOAK_REALM_IMPORT_FILE_DST: "{{ [KEYCLOAK_REALM_IMPORT_DIR_HOST,'realm.json'] | path_join }}"
|
||||||
|
|
||||||
## Credentials
|
## Credentials
|
||||||
KEYCLOAK_ADMIN: "{{ applications | get_app_conf(application_id, 'users.administrator.username') }}"
|
|
||||||
KEYCLOAK_ADMIN_PASSWORD: "{{ applications | get_app_conf(application_id, 'credentials.administrator_password') }}"
|
### Bootstrap
|
||||||
|
KEYCLOAK_BOOTSTRAP_ADMIN_USERNAME: "{{ applications | get_app_conf(application_id, 'accounts.bootstrap.username') }}"
|
||||||
|
KEYCLOAK_BOOTSTRAP_ADMIN_PASSWORD: "{{ applications | get_app_conf(application_id, 'credentials.administrator_password') }}"
|
||||||
|
|
||||||
|
### Permanent
|
||||||
|
KEYCLOAK_PERMANENT_ADMIN_USERNAME: "{{ applications | get_app_conf(application_id, 'accounts.system.username') }}"
|
||||||
|
KEYCLOAK_PERMANENT_ADMIN_PASSWORD: "{{ applications | get_app_conf(application_id, 'credentials.administrator_password') }}"
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
KEYCLOAK_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.name') }}" # Name of the keycloak docker container
|
KEYCLOAK_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.name') }}"
|
||||||
KEYCLOAK_EXEC_KCADM: "docker exec -i {{ KEYCLOAK_CONTAINER }} /opt/keycloak/bin/kcadm.sh" # Init script for keycloak
|
KEYCLOAK_EXEC_CONTAINER: "docker exec -i {{ KEYCLOAK_CONTAINER }}"
|
||||||
KEYCLOAK_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.image') }}" # Keycloak docker image
|
KEYCLOAK_KCADM: "/opt/keycloak/bin/kcadm.sh"
|
||||||
KEYCLOAK_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.version') }}" # Keycloak docker version
|
KEYCLOAK_EXEC_KCADM: "{{ KEYCLOAK_EXEC_CONTAINER }} {{ KEYCLOAK_KCADM }}"
|
||||||
|
KEYCLOAK_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.image') }}"
|
||||||
|
KEYCLOAK_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.version') }}"
|
||||||
|
|
||||||
## Server
|
## Server
|
||||||
KEYCLOAK_SERVER_HOST: "127.0.0.1:{{ ports.localhost.http[application_id] }}"
|
KEYCLOAK_SERVER_HOST: "127.0.0.1:{{ ports.localhost.http[application_id] }}"
|
||||||
@@ -69,11 +77,6 @@ KEYCLOAK_LDAP_USER_OBJECT_CLASSES: >
|
|||||||
) | join(', ')
|
) | join(', ')
|
||||||
}}
|
}}
|
||||||
|
|
||||||
## 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
|
# Dictionaries
|
||||||
KEYCLOAK_DICTIONARY_REALM_RAW: "{{ lookup('template', 'import/realm.json.j2') }}"
|
KEYCLOAK_DICTIONARY_REALM_RAW: "{{ lookup('template', 'import/realm.json.j2') }}"
|
||||||
KEYCLOAK_DICTIONARY_REALM: >-
|
KEYCLOAK_DICTIONARY_REALM: >-
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: true
|
css: true
|
||||||
desktop: true
|
desktop: true
|
||||||
logout: false
|
logout: false
|
||||||
server:
|
server:
|
||||||
csp:
|
csp:
|
||||||
whitelist:
|
whitelist:
|
||||||
@@ -16,14 +16,15 @@ server:
|
|||||||
font-src:
|
font-src:
|
||||||
- https://cdnjs.cloudflare.com
|
- https://cdnjs.cloudflare.com
|
||||||
frame-src:
|
frame-src:
|
||||||
- "{{ WEB_PROTOCOL }}://*.{{ PRIMARY_DOMAIN }}" # Makes sense that all of the website content is available in the navigator
|
# Makes sense that all of the website content is available in the navigator
|
||||||
|
- "{{ WEB_PROTOCOL }}://*.{{ PRIMARY_DOMAIN }}"
|
||||||
flags:
|
flags:
|
||||||
style-src:
|
style-src:
|
||||||
unsafe-inline: true
|
unsafe-inline: true
|
||||||
script-src:
|
script-src:
|
||||||
unsafe-eval: true
|
unsafe-eval: true
|
||||||
script-src-elem:
|
script-src-elem:
|
||||||
unsafe-inline: true
|
unsafe-inline: true
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "slides.{{ PRIMARY_DOMAIN }}"
|
- "slides.{{ PRIMARY_DOMAIN }}"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
galaxy_info:
|
galaxy_info:
|
||||||
author: "Kevin Veen-Birkenbach"
|
author: "Kevin Veen-Birkenbach"
|
||||||
description: "An interactive presentation platform focused on guiding end-users through the practical use of the Infinito.Nexus software. Designed to demonstrate features, workflows, and real-world applications for Administrators, Developers, End-Users, Businesses, and Investors."
|
description: "An interactive presentation platform focused on guiding end-users through the practical use of the Infinito.Nexus software. Designed to demonstrate features, workflows, and real-world applications for Administrators, Developers, End-Users, Businesses, and Investors."
|
||||||
license: "Infinito.Nexus NonCommercial License"
|
license: "Infinito.Nexus NonCommercial License"
|
||||||
license_url: "https://s.infinito.nexus/license"
|
license_url: "https://s.infinito.nexus/license"
|
||||||
company: |
|
company: |
|
||||||
Kevin Veen-Birkenbach
|
Kevin Veen-Birkenbach
|
||||||
Consulting & Coaching Solutions
|
Consulting & Coaching Solutions
|
||||||
|
|||||||
@@ -13,4 +13,3 @@
|
|||||||
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
||||||
|
|
||||||
{% include 'roles/docker-compose/templates/networks.yml.j2' %}
|
{% include 'roles/docker-compose/templates/networks.yml.j2' %}
|
||||||
|
|
||||||
|
|||||||
@@ -28,14 +28,17 @@ BUILTIN_FILTERS: Set[str] = {
|
|||||||
"int", "join", "last", "length", "list", "lower", "map", "min", "max", "random",
|
"int", "join", "last", "length", "list", "lower", "map", "min", "max", "random",
|
||||||
"reject", "rejectattr", "replace", "reverse", "round", "safe", "select",
|
"reject", "rejectattr", "replace", "reverse", "round", "safe", "select",
|
||||||
"selectattr", "slice", "sort", "string", "striptags", "sum", "title", "trim",
|
"selectattr", "slice", "sort", "string", "striptags", "sum", "title", "trim",
|
||||||
"truncate", "unique", "upper", "urlencode", "urlize", "wordcount", "xmlattr",
|
"truncate", "unique", "upper", "urlencode", "urlize", "wordcount", "xmlattr","contains",
|
||||||
|
|
||||||
# Common Ansible filters (subset, extend as needed)
|
# Common Ansible filters (subset, extend as needed)
|
||||||
"b64decode", "b64encode", "basename", "dirname", "from_json", "to_json",
|
"b64decode", "b64encode", "basename", "dirname", "from_json", "to_json",
|
||||||
"from_yaml", "to_yaml", "combine", "difference", "intersect",
|
"from_yaml", "to_yaml", "combine", "difference", "intersect",
|
||||||
"flatten", "zip", "regex_search", "regex_replace", "bool",
|
"flatten", "zip", "regex_search", "regex_replace", "bool",
|
||||||
"type_debug", "json_query", "mandatory", "hash", "checksum",
|
"type_debug", "json_query", "mandatory", "hash", "checksum",
|
||||||
"lower", "upper", "capitalize", "unique", "dict2items", "items2dict", "password_hash", "path_join", "product", "quote", "split", "ternary", "to_nice_yaml", "tojson",
|
"lower", "upper", "capitalize", "unique", "dict2items", "items2dict",
|
||||||
|
"password_hash", "path_join", "product", "quote", "split", "ternary", "to_nice_yaml",
|
||||||
|
"tojson", "to_nice_json",
|
||||||
|
|
||||||
|
|
||||||
# Date/time-ish
|
# Date/time-ish
|
||||||
"strftime",
|
"strftime",
|
||||||
|
|||||||
Reference in New Issue
Block a user