Add sunbeam-sccache bucket and a dedicated sccache S3 identity scoped to Read/Write/List/Tagging on that bucket only. Bump volume server max from 50 to 100 (was full, blocking all new writes).
219 lines
9.3 KiB
Bash
Executable File
219 lines
9.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Seed all secrets for the local dev stack.
|
|
# - Initializes OpenBao (if needed) and stores root token + unseal key
|
|
# - Sets postgres user passwords
|
|
# - Creates K8s secrets consumed by each service
|
|
# - Stores all secrets in OpenBao as source of truth
|
|
#
|
|
# Idempotent: safe to run multiple times.
|
|
set -euo pipefail
|
|
|
|
CTX="--context=sunbeam"
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
# Deterministic local-dev passwords (simple, memorable, not for production)
|
|
DB_PASSWORD="localdev"
|
|
S3_ACCESS_KEY="minioadmin"
|
|
S3_SECRET_KEY="minioadmin"
|
|
SCCACHE_ACCESS_KEY="sccache-local"
|
|
SCCACHE_SECRET_KEY="sccache-local-secret"
|
|
HYDRA_SYSTEM_SECRET="local-hydra-system-secret-at-least-16"
|
|
HYDRA_COOKIE_SECRET="local-hydra-cookie-secret-at-least-16"
|
|
HYDRA_PAIRWISE_SALT="local-hydra-pairwise-salt-value-1"
|
|
LIVEKIT_API_KEY="devkey"
|
|
LIVEKIT_API_SECRET="secret-placeholder"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Helper
|
|
# ---------------------------------------------------------------------------
|
|
ensure_ns() {
|
|
kubectl $CTX create namespace "$1" --dry-run=client -o yaml | kubectl $CTX apply -f - 2>/dev/null
|
|
}
|
|
|
|
create_secret() {
|
|
local ns="$1"; shift
|
|
local name="$1"; shift
|
|
# remaining args are --from-literal=key=value
|
|
kubectl $CTX create secret generic "$name" -n "$ns" "$@" \
|
|
--dry-run=client -o yaml | kubectl $CTX apply -f -
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 1. Wait for postgres to be ready
|
|
# ---------------------------------------------------------------------------
|
|
echo "==> Waiting for postgres cluster..."
|
|
for i in $(seq 1 60); do
|
|
PHASE=$(kubectl $CTX -n data get cluster postgres -o jsonpath='{.status.phase}' 2>/dev/null || echo "")
|
|
if [[ "$PHASE" == "Cluster in healthy state" ]]; then
|
|
echo " Postgres is ready."
|
|
break
|
|
fi
|
|
if [[ $i -eq 60 ]]; then
|
|
echo "WARN: Postgres not ready after 5 min, continuing anyway..."
|
|
fi
|
|
sleep 5
|
|
done
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 2. Set postgres user passwords
|
|
# ---------------------------------------------------------------------------
|
|
echo "==> Setting postgres user passwords..."
|
|
PG_POD=$(kubectl $CTX -n data get pods -l cnpg.io/cluster=postgres,role=primary -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
|
|
if [[ -n "$PG_POD" ]]; then
|
|
for user in kratos hydra gitea hive docs meet drive messages conversations people find penpot stalwart; do
|
|
kubectl $CTX -n data exec "$PG_POD" -c postgres -- \
|
|
psql -U postgres -c "ALTER USER $user WITH PASSWORD '$DB_PASSWORD';" 2>/dev/null || true
|
|
done
|
|
echo " Done."
|
|
else
|
|
echo "WARN: No postgres primary pod found, skipping password setup."
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 3. Create K8s secrets for each service
|
|
# ---------------------------------------------------------------------------
|
|
echo "==> Creating K8s secrets..."
|
|
|
|
# Ory namespace
|
|
ensure_ns ory
|
|
# Secret name must match chart release name (secret.enabled: false means chart uses release name)
|
|
create_secret ory hydra \
|
|
--from-literal=dsn="postgresql://hydra:${DB_PASSWORD}@postgres-rw.data.svc.cluster.local:5432/hydra_db?sslmode=disable" \
|
|
--from-literal=secretsSystem="$HYDRA_SYSTEM_SECRET" \
|
|
--from-literal=secretsCookie="$HYDRA_COOKIE_SECRET" \
|
|
--from-literal=pairwise-salt="$HYDRA_PAIRWISE_SALT"
|
|
|
|
# Kratos chart (secret.enabled: true, nameOverride: kratos-secrets) creates kratos-secrets
|
|
# from Helm values — DSN is in kratos-values.yaml, random secrets generated by chart.
|
|
# This create is a no-op placeholder; chart apply overwrites with Helm-generated values.
|
|
|
|
# Devtools namespace
|
|
ensure_ns devtools
|
|
create_secret devtools gitea-db-credentials \
|
|
--from-literal=password="$DB_PASSWORD"
|
|
|
|
create_secret devtools gitea-s3-credentials \
|
|
--from-literal=access-key="$S3_ACCESS_KEY" \
|
|
--from-literal=secret-key="$S3_SECRET_KEY"
|
|
|
|
create_secret devtools penpot-db-credentials \
|
|
--from-literal=password="$DB_PASSWORD"
|
|
|
|
create_secret devtools penpot-s3-credentials \
|
|
--from-literal=access-key="$S3_ACCESS_KEY" \
|
|
--from-literal=secret-key="$S3_SECRET_KEY"
|
|
|
|
create_secret devtools penpot-app-secrets \
|
|
--from-literal=secret-key="penpot-local-secret-key-not-for-production"
|
|
|
|
# Storage namespace
|
|
ensure_ns storage
|
|
create_secret storage seaweedfs-s3-credentials \
|
|
--from-literal=S3_ACCESS_KEY="$S3_ACCESS_KEY" \
|
|
--from-literal=S3_SECRET_KEY="$S3_SECRET_KEY"
|
|
|
|
# La Suite namespace
|
|
ensure_ns lasuite
|
|
create_secret lasuite seaweedfs-s3-credentials \
|
|
--from-literal=S3_ACCESS_KEY="$S3_ACCESS_KEY" \
|
|
--from-literal=S3_SECRET_KEY="$S3_SECRET_KEY"
|
|
|
|
create_secret lasuite hive-db-url \
|
|
--from-literal=url="postgresql://hive:${DB_PASSWORD}@postgres-rw.data.svc.cluster.local:5432/hive_db"
|
|
|
|
create_secret lasuite hive-oidc \
|
|
--from-literal=client-id="hive-local" \
|
|
--from-literal=client-secret="hive-local-secret"
|
|
|
|
# People (desk)
|
|
create_secret lasuite people-db-credentials \
|
|
--from-literal=password="$DB_PASSWORD"
|
|
|
|
create_secret lasuite people-django-secret \
|
|
--from-literal=DJANGO_SECRET_KEY="local-dev-people-django-secret-key-not-for-production"
|
|
|
|
# Stalwart namespace
|
|
ensure_ns stalwart
|
|
create_secret stalwart stalwart-db-credentials \
|
|
--from-literal=password="$DB_PASSWORD"
|
|
|
|
create_secret stalwart stalwart-app-secrets \
|
|
--from-literal=admin-password="stalwart-local-admin-password" \
|
|
--from-literal=dkim-private-key="placeholder-generate-real-key-for-production"
|
|
|
|
create_secret stalwart seaweedfs-s3-credentials \
|
|
--from-literal=S3_ACCESS_KEY="$S3_ACCESS_KEY" \
|
|
--from-literal=S3_SECRET_KEY="$S3_SECRET_KEY"
|
|
|
|
# Media namespace
|
|
ensure_ns media
|
|
|
|
echo " Done."
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 4. Initialize and unseal OpenBao (if deployed)
|
|
# ---------------------------------------------------------------------------
|
|
echo "==> Checking OpenBao..."
|
|
OB_POD=$(kubectl $CTX -n data get pods -l app.kubernetes.io/name=openbao,component=server -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
|
|
if [[ -z "$OB_POD" ]]; then
|
|
echo " OpenBao pod not found, skipping."
|
|
else
|
|
# Wait for pod to be running (not necessarily ready — it won't be ready until unsealed)
|
|
kubectl $CTX -n data wait pod "$OB_POD" --for=jsonpath='{.status.phase}'=Running --timeout=120s 2>/dev/null || true
|
|
|
|
# Check if initialized
|
|
INIT_STATUS=$(kubectl $CTX -n data exec "$OB_POD" -c openbao -- bao status -format=json 2>/dev/null | grep '"initialized"' | grep -c 'true' || echo "0")
|
|
|
|
if [[ "$INIT_STATUS" != "1" ]]; then
|
|
echo "==> Initializing OpenBao..."
|
|
INIT_OUTPUT=$(kubectl $CTX -n data exec "$OB_POD" -c openbao -- bao operator init -key-shares=1 -key-threshold=1 -format=json 2>/dev/null)
|
|
UNSEAL_KEY=$(echo "$INIT_OUTPUT" | jq -r '.unseal_keys_b64[0]')
|
|
ROOT_TOKEN=$(echo "$INIT_OUTPUT" | jq -r '.root_token')
|
|
|
|
# Store keys in K8s secret
|
|
create_secret data openbao-keys \
|
|
--from-literal=key="$UNSEAL_KEY" \
|
|
--from-literal=root-token="$ROOT_TOKEN"
|
|
echo " Initialized. Keys stored in secret/openbao-keys."
|
|
else
|
|
echo " Already initialized."
|
|
# Read unseal key from existing secret
|
|
UNSEAL_KEY=$(kubectl $CTX -n data get secret openbao-keys -o jsonpath='{.data.key}' 2>/dev/null | base64 -d || echo "")
|
|
ROOT_TOKEN=$(kubectl $CTX -n data get secret openbao-keys -o jsonpath='{.data.root-token}' 2>/dev/null | base64 -d || echo "")
|
|
fi
|
|
|
|
# Unseal if sealed
|
|
SEALED=$(kubectl $CTX -n data exec "$OB_POD" -c openbao -- bao status -format=json 2>/dev/null | grep '"sealed"' | grep -c 'true' || echo "0")
|
|
if [[ "$SEALED" == "1" && -n "$UNSEAL_KEY" ]]; then
|
|
echo "==> Unsealing OpenBao..."
|
|
kubectl $CTX -n data exec "$OB_POD" -c openbao -- bao operator unseal "$UNSEAL_KEY"
|
|
echo " Unsealed."
|
|
fi
|
|
|
|
# Seed secrets into OpenBao
|
|
if [[ -n "$ROOT_TOKEN" ]]; then
|
|
echo "==> Seeding secrets into OpenBao..."
|
|
kubectl $CTX -n data exec "$OB_POD" -c openbao -- sh -c "
|
|
export BAO_ADDR=http://127.0.0.1:8200
|
|
export BAO_TOKEN='$ROOT_TOKEN'
|
|
|
|
bao secrets enable -path=secret -version=2 kv 2>/dev/null || true
|
|
|
|
bao kv put secret/postgres password='$DB_PASSWORD'
|
|
bao kv put secret/hydra db-password='$DB_PASSWORD' system-secret='$HYDRA_SYSTEM_SECRET' cookie-secret='$HYDRA_COOKIE_SECRET' pairwise-salt='$HYDRA_PAIRWISE_SALT'
|
|
bao kv put secret/kratos db-password='$DB_PASSWORD'
|
|
bao kv put secret/gitea db-password='$DB_PASSWORD' s3-access-key='$S3_ACCESS_KEY' s3-secret-key='$S3_SECRET_KEY'
|
|
bao kv put secret/seaweedfs access-key='$S3_ACCESS_KEY' secret-key='$S3_SECRET_KEY' sccache-access-key='$SCCACHE_ACCESS_KEY' sccache-secret-key='$SCCACHE_SECRET_KEY'
|
|
bao kv put secret/hive db-url='postgresql://hive:${DB_PASSWORD}@postgres-rw.data.svc.cluster.local:5432/hive_db' oidc-client-id='hive-local' oidc-client-secret='hive-local-secret'
|
|
bao kv put secret/people db-password='$DB_PASSWORD' django-secret-key='local-dev-people-django-secret-key-not-for-production'
|
|
bao kv put secret/penpot db-password='$DB_PASSWORD' secret-key='penpot-local-secret-key-not-for-production'
|
|
bao kv put secret/livekit api-key='$LIVEKIT_API_KEY' api-secret='$LIVEKIT_API_SECRET'
|
|
bao kv put secret/stalwart admin-password='stalwart-local-admin-password' dkim-private-key='placeholder-generate-real-key-for-production'
|
|
" 2>/dev/null
|
|
echo " Done."
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo "==> All secrets seeded."
|