14 Commits

Author SHA1 Message Date
0b86b2f057 Set MODE_CLEANUP default true and solved tld localhost user name bug 2025-10-12 01:15:52 +02:00
80e048a274 Fix: make EspoCRM entrypoint POSIX-compliant and remove illegal 'pipefail' usage
The previous entrypoint script used 'set -euo pipefail', which caused runtime errors
because /bin/sh (Dash/BusyBox) does not support 'pipefail'. This commit makes the
entrypoint fully POSIX-safe, adds robust fallbacks for missing scripts, and improves
logging. Also removes a trailing newline in the navigator Docker Compose template.

Related ChatGPT discussion: https://chatgpt.com/share/68eab0b7-7a64-800f-a8aa-e7d7262a262e
2025-10-11 21:33:07 +02:00
2610aec293 Deactivated cakeday plugin because it's an onboard plugin 2025-10-11 18:23:38 +02:00
07db162368 Reformated navigation role 2025-10-11 18:04:58 +02:00
a526d1adc4 Solved Keycloak Master Email Configuration Update settings 2025-10-11 16:57:36 +02:00
ca95079111 Added Email Configuration for Keycloak Master Realm 2025-10-11 16:45:50 +02:00
e410d66cb4 Add health check for Keycloak container and grant global 'admin' realm role to permanent admin user
This update waits for the Keycloak container to become healthy before attempting login and replaces the old realm-management based role assignment with the global 'admin' realm role.
See: https://chatgpt.com/share/68e99953-e988-800f-8b82-9ffb14c11910
2025-10-11 01:40:48 +02:00
ab48cf522f fix(keycloak): make permanent admin creation idempotent and fix password command
- prevent task failure when 'User exists with same username'
- remove invalid '--temporary false' flag from set-password command
- ensure realm-admin role grant remains idempotent

See: https://chatgpt.com/share/68e99271-fdb0-800f-a8ad-11c15d02a670
2025-10-11 01:10:57 +02:00
41c12bdc12 Refactor Keycloak permanent admin creation:
- Remove jq dependency to avoid container command errors
- Use username-based operations instead of user ID lookups
- Improve idempotency and portability across environments

See: https://chatgpt.com/share/68e98e77-9b3c-800f-8393-71b0be22cb46
2025-10-11 00:54:04 +02:00
aae463b602 Optimized keycloak setup procedures 2025-10-11 00:20:27 +02:00
bb50551533 Restrucutred keycloak accounts 2025-10-10 23:40:58 +02:00
098099b41e Refactored web-app-keycloak 2025-10-10 22:45:26 +02:00
0a7d767252 Added contains to filter 2025-10-10 22:16:23 +02:00
d88599f76c Added 'to_nice_json' exception 2025-10-10 22:16:22 +02:00
20 changed files with 242 additions and 126 deletions

View File

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

View File

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

View File

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

View File

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

View File

@@ -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
@@ -50,3 +50,9 @@ 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 }}"

View 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

View File

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

View 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

View 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 }}"

View 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 }}"

View File

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

View File

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

View File

@@ -1,3 +0,0 @@
users:
administrator:
username: "administrator"

View File

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

View File

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

View File

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

View File

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

View File

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