mirror of
https://gitlab.kube.huskypup.net/Scooby/Homelabv4.git
synced 2026-08-21 05:26:49 +00:00
132 lines
5.3 KiB
Bash
Executable File
132 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Teslamate Bootstrap - Auto-configure PostgreSQL with ESO
|
|
set -euo pipefail
|
|
|
|
echo "=== Teslamate Bootstrap - Fully Automated ==="
|
|
|
|
# Change to the apps directory for relative paths
|
|
cd "$(dirname "$0")/../apps" || exit 1
|
|
|
|
NS=teslamate
|
|
CLUSTER=pg-teslamate
|
|
|
|
# 1) Ensure namespace
|
|
kubectl get ns "${NS}" >/dev/null 2>&1 || kubectl create ns "${NS}"
|
|
|
|
# 2) Apply CNPG cluster (auto-generates DB password)
|
|
echo "Applying Teslamate PostgreSQL cluster..."
|
|
kubectl apply -f teslamate/cnpg-cluster.yaml
|
|
|
|
# 3) Wait for CNPG cluster
|
|
echo "Waiting for CNPG cluster ${CLUSTER}..."
|
|
kubectl -n "${NS}" wait --for=condition=Ready "cluster/${CLUSTER}" --timeout=300s
|
|
|
|
# 3.5) Set up PostgreSQL extensions and grant superuser
|
|
echo "Setting up PostgreSQL extensions for Teslamate..."
|
|
PRIMARY_POD=$(kubectl get pod -n "${NS}" -l cnpg.io/cluster="${CLUSTER}",role=primary -o jsonpath='{.items[0].metadata.name}')
|
|
|
|
if [ -n "$PRIMARY_POD" ]; then
|
|
echo "Granting superuser to teslamate user..."
|
|
kubectl exec -n "${NS}" "$PRIMARY_POD" -- psql -U postgres -c "ALTER USER teslamate WITH SUPERUSER;" 2>/dev/null || echo " (user may already have superuser)"
|
|
|
|
echo "Creating required PostgreSQL extensions..."
|
|
kubectl exec -n "${NS}" "$PRIMARY_POD" -- psql -U postgres -d teslamate -c "CREATE EXTENSION IF NOT EXISTS cube;" 2>/dev/null || echo " (cube extension may already exist)"
|
|
kubectl exec -n "${NS}" "$PRIMARY_POD" -- psql -U postgres -d teslamate -c "CREATE EXTENSION IF NOT EXISTS earthdistance;" 2>/dev/null || echo " (earthdistance extension may already exist)"
|
|
|
|
echo "✅ PostgreSQL extensions configured"
|
|
else
|
|
echo "⚠️ Warning: Could not find primary pod, skipping extension setup"
|
|
fi
|
|
|
|
# 4) Apply ESO secrets (auto-rotate DB passwords)
|
|
echo "Applying Teslamate ESO secrets (auto-generates passwords)..."
|
|
kubectl apply -f teslamate/cnpg-secrets.yaml
|
|
|
|
# 5) Wait for password to be generated
|
|
echo "Waiting for ESO to generate database password..."
|
|
for i in {1..30}; do
|
|
if kubectl -n "${NS}" get secret pg-teslamate-app >/dev/null 2>&1; then
|
|
echo "✅ Database password generated"
|
|
break
|
|
fi
|
|
echo " waiting for secret... (attempt $i/30)"
|
|
sleep 2
|
|
done
|
|
|
|
# 6) Initialize encryption key in Vault if it doesn't exist
|
|
echo "Initializing encryption key in Vault..."
|
|
|
|
# Get Vault root token from secret
|
|
VAULT_ROOT_TOKEN=$(kubectl -n vault get secret vault-init-keys -o jsonpath='{.data.VAULT_ROOT_TOKEN}' 2>/dev/null | base64 -d || echo "")
|
|
|
|
if [ -z "$VAULT_ROOT_TOKEN" ]; then
|
|
echo "⚠️ Warning: Could not retrieve Vault root token from secret vault-init-keys"
|
|
echo "Skipping encryption key creation. You'll need to create it manually."
|
|
echo ""
|
|
echo "To create the encryption key manually:"
|
|
echo " ENCRYPTION_KEY=\$(openssl rand -base64 32)"
|
|
echo " kubectl exec -n vault vault-0 -- vault kv put secret/teslamate/config encryption_key=\"\${ENCRYPTION_KEY}\""
|
|
echo ""
|
|
# Continue anyway - the ExternalSecret will show an error if the key doesn't exist
|
|
else
|
|
# Check if the secret already exists in Vault
|
|
if kubectl exec -n vault vault-0 -- env VAULT_TOKEN="${VAULT_ROOT_TOKEN}" vault kv get secret/teslamate/config >/dev/null 2>&1; then
|
|
echo "✅ Encryption key already exists in Vault"
|
|
else
|
|
echo "Generating new encryption key..."
|
|
ENCRYPTION_KEY=$(openssl rand -base64 32)
|
|
|
|
# Write to Vault using root token
|
|
if kubectl exec -n vault vault-0 -- env VAULT_TOKEN="${VAULT_ROOT_TOKEN}" vault kv put secret/teslamate/config encryption_key="${ENCRYPTION_KEY}"; then
|
|
echo "✅ Encryption key stored in Vault"
|
|
else
|
|
echo "❌ Failed to write to Vault"
|
|
echo "Please create the encryption key manually:"
|
|
echo " kubectl exec -n vault vault-0 -- env VAULT_TOKEN=\"${VAULT_ROOT_TOKEN}\" vault kv put secret/teslamate/config encryption_key=\"${ENCRYPTION_KEY}\""
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# 7) Apply Teslamate config ExternalSecret
|
|
echo "Applying Teslamate config ExternalSecret..."
|
|
kubectl apply -f teslamate/external-secret.yaml
|
|
|
|
# 8) Wait for teslamate-config-secret to be created
|
|
echo "Waiting for teslamate-config-secret to be synced from Vault..."
|
|
SECRET_SYNCED=false
|
|
for i in {1..30}; do
|
|
if kubectl -n "${NS}" get secret teslamate-config-secret >/dev/null 2>&1; then
|
|
echo "✅ teslamate-config-secret synced successfully"
|
|
SECRET_SYNCED=true
|
|
break
|
|
fi
|
|
echo " waiting for secret... (attempt $i/30)"
|
|
sleep 2
|
|
done
|
|
|
|
# 9) If ESO failed to sync, create secret manually as fallback
|
|
if [ "$SECRET_SYNCED" = "false" ]; then
|
|
echo "⚠️ ExternalSecret failed to sync (ClusterSecretStore issue)"
|
|
echo "Creating teslamate-config-secret manually from Vault..."
|
|
|
|
if [ -n "$VAULT_ROOT_TOKEN" ]; then
|
|
ENCRYPTION_KEY=$(kubectl exec -n vault vault-0 -- env VAULT_TOKEN="${VAULT_ROOT_TOKEN}" vault kv get -field=encryption_key secret/teslamate/config 2>/dev/null || echo "")
|
|
|
|
if [ -n "$ENCRYPTION_KEY" ]; then
|
|
kubectl create secret generic teslamate-config-secret -n "${NS}" \
|
|
--from-literal=encryption-key="${ENCRYPTION_KEY}" \
|
|
--dry-run=client -o yaml | kubectl apply -f -
|
|
echo "✅ Created teslamate-config-secret manually"
|
|
else
|
|
echo "❌ Failed to retrieve encryption key from Vault"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "❌ Cannot create secret manually - no Vault token"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo "✅ Teslamate bootstrap complete - fully automated!"
|