mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
The OIDC admin wiring is gated on SSO alone, and SSO is 'web-app-keycloak' in group_names. Round 1 takes keycloak variant 1, which pins ldap off, so svc-db-openldap is not in the closure; the block still resolved its swarm service and the waiter spent 600 attempts on a service that does not exist (run 33698844864, Mattermost#1, 25 minutes). In compose the same block would have died on a missing container, so the defect is mode-independent.
The number it fetched is already in the registry: svc-db-openldap/tasks/04_users.yml:118 writes uidNumber from the same lookup('users'), and an earlier run shows inventory uid 1001 against ldapsearch 1001. Reading it directly removes the cross-stack exec entirely.
Keycloak's mattermost-id mapper reads the uidNumber attribute, which until now only the LDAP federation wrote, so the same round would have produced no id claim to match. ensure_realm_user.sh now mirrors the uid into that attribute whenever it is passed one, leaving callers without a uid unchanged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
105 lines
3.1 KiB
Bash
Executable File
105 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
###############################################################################
|
|
# Ensure a Keycloak realm user exists with the desired profile/password.
|
|
#
|
|
# Runs on the host and executes kcadm inside the Keycloak container.
|
|
#
|
|
# REQUIRED environment variables:
|
|
# KEYCLOAK_EXEC_CONTAINER
|
|
# KEYCLOAK_KCADM
|
|
# KEYCLOAK_REALM
|
|
# KEYCLOAK_USERNAME
|
|
# KEYCLOAK_PASSWORD
|
|
#
|
|
# OPTIONAL:
|
|
# KEYCLOAK_EMAIL
|
|
# KEYCLOAK_FIRSTNAME
|
|
# KEYCLOAK_LASTNAME
|
|
# KEYCLOAK_USER_ENABLED true|false (default: true)
|
|
# KEYCLOAK_UIDNUMBER posix uid, mirrored into the uidNumber attribute
|
|
###############################################################################
|
|
|
|
: "${KEYCLOAK_EXEC_CONTAINER:?missing KEYCLOAK_EXEC_CONTAINER}"
|
|
: "${KEYCLOAK_KCADM:?missing KEYCLOAK_KCADM}"
|
|
: "${KEYCLOAK_REALM:?missing KEYCLOAK_REALM}"
|
|
: "${KEYCLOAK_USERNAME:?missing KEYCLOAK_USERNAME}"
|
|
: "${KEYCLOAK_PASSWORD:?missing KEYCLOAK_PASSWORD}"
|
|
|
|
KEYCLOAK_EMAIL="${KEYCLOAK_EMAIL:-}"
|
|
KEYCLOAK_FIRSTNAME="${KEYCLOAK_FIRSTNAME:-}"
|
|
KEYCLOAK_LASTNAME="${KEYCLOAK_LASTNAME:-}"
|
|
KEYCLOAK_USER_ENABLED="${KEYCLOAK_USER_ENABLED:-true}"
|
|
KEYCLOAK_UIDNUMBER="${KEYCLOAK_UIDNUMBER:-}"
|
|
|
|
# shellcheck disable=SC2016 # Inner $vars are intentionally expanded by the container shell, not the host.
|
|
${KEYCLOAK_EXEC_CONTAINER} sh -lc '
|
|
set -euo pipefail
|
|
|
|
USERNAME="$1"
|
|
PASSWORD="$2"
|
|
REALM="$3"
|
|
EMAIL="$4"
|
|
FIRSTNAME="$5"
|
|
LASTNAME="$6"
|
|
ENABLED="$7"
|
|
KCADM="$8"
|
|
UIDNUMBER="$9"
|
|
|
|
RAW="$($KCADM get users -r "$REALM" -q username="$USERNAME" --fields id --format csv --noquotes 2>&1 || true)"
|
|
USER_ID="$(printf "%s\n" "$RAW" \
|
|
| grep -Eio "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" \
|
|
| head -n1 || true)"
|
|
|
|
CREATED=false
|
|
if [ -z "${USER_ID:-}" ]; then
|
|
$KCADM create users -r "$REALM" \
|
|
-s "username=$USERNAME" \
|
|
-s "enabled=$ENABLED" \
|
|
-s "email=$EMAIL" \
|
|
-s "firstName=$FIRSTNAME" \
|
|
-s "lastName=$LASTNAME"
|
|
CREATED=true
|
|
|
|
RAW="$($KCADM get users -r "$REALM" -q username="$USERNAME" --fields id --format csv --noquotes 2>&1 || true)"
|
|
USER_ID="$(printf "%s\n" "$RAW" \
|
|
| grep -Eio "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" \
|
|
| head -n1 || true)"
|
|
fi
|
|
|
|
if [ -z "${USER_ID:-}" ]; then
|
|
echo "[keycloak][user] failed to resolve user id for $USERNAME in realm $REALM" >&2
|
|
exit 1
|
|
fi
|
|
|
|
$KCADM update users/$USER_ID -r "$REALM" \
|
|
-s "enabled=$ENABLED" \
|
|
-s "email=$EMAIL" \
|
|
-s "firstName=$FIRSTNAME" \
|
|
-s "lastName=$LASTNAME"
|
|
|
|
if [ -n "$UIDNUMBER" ]; then
|
|
$KCADM update users/$USER_ID -r "$REALM" -s "attributes.uidNumber=$UIDNUMBER"
|
|
fi
|
|
|
|
$KCADM set-password -r "$REALM" \
|
|
--username "$USERNAME" \
|
|
--new-password "$PASSWORD"
|
|
|
|
if [ "$CREATED" = true ]; then
|
|
echo "[keycloak][user] created: $USERNAME ($USER_ID)"
|
|
else
|
|
echo "[keycloak][user] updated: $USERNAME ($USER_ID)"
|
|
fi
|
|
' sh \
|
|
"${KEYCLOAK_USERNAME}" \
|
|
"${KEYCLOAK_PASSWORD}" \
|
|
"${KEYCLOAK_REALM}" \
|
|
"${KEYCLOAK_EMAIL}" \
|
|
"${KEYCLOAK_FIRSTNAME}" \
|
|
"${KEYCLOAK_LASTNAME}" \
|
|
"${KEYCLOAK_USER_ENABLED}" \
|
|
"${KEYCLOAK_KCADM}" \
|
|
"${KEYCLOAK_UIDNUMBER}"
|