#!/usr/bin/env bash set -Eeuo pipefail # Credentials Update Script # Updates credentials in an existing LXC container SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/libsupabase.sh" usage() { cat >&2 <<'EOF' Usage: bash update_credentials.sh --ctid [options] Required: --ctid Container ID Credential Options: --credentials-file Path to credentials JSON file (default: credentials/.json) --ollama-url Update Ollama URL (e.g., http://ollama.local:11434) --ollama-model Update Ollama chat model --embedding-model Update embedding model --pg-password Update PostgreSQL password --n8n-password Update n8n owner password Examples: # Update from credentials file bash update_credentials.sh --ctid 769276659 --credentials-file credentials/sb-1769276659.json # Update specific credentials bash update_credentials.sh --ctid 769276659 --ollama-url http://ollama.local:11434 # Update multiple credentials bash update_credentials.sh --ctid 769276659 \ --ollama-url http://ollama.local:11434 \ --ollama-model llama3.2:3b EOF } # Parse arguments CTID="" CREDENTIALS_FILE="" OLLAMA_URL="" OLLAMA_MODEL="" EMBEDDING_MODEL="" PG_PASSWORD="" N8N_PASSWORD="" while [[ $# -gt 0 ]]; do case "$1" in --ctid) CTID="${2:-}"; shift 2 ;; --credentials-file) CREDENTIALS_FILE="${2:-}"; shift 2 ;; --ollama-url) OLLAMA_URL="${2:-}"; shift 2 ;; --ollama-model) OLLAMA_MODEL="${2:-}"; shift 2 ;; --embedding-model) EMBEDDING_MODEL="${2:-}"; shift 2 ;; --pg-password) PG_PASSWORD="${2:-}"; shift 2 ;; --n8n-password) N8N_PASSWORD="${2:-}"; shift 2 ;; --help|-h) usage; exit 0 ;; *) die "Unknown option: $1 (use --help)" ;; esac done [[ -n "$CTID" ]] || die "Missing required parameter: --ctid" # Check if container exists pct status "$CTID" >/dev/null 2>&1 || die "Container $CTID not found" info "Updating credentials for container $CTID" # Get container hostname CT_HOSTNAME=$(pct exec "$CTID" -- hostname 2>/dev/null || echo "") [[ -n "$CT_HOSTNAME" ]] || die "Could not determine container hostname" info "Container hostname: $CT_HOSTNAME" # If credentials file specified, load it if [[ -n "$CREDENTIALS_FILE" ]]; then [[ -f "$CREDENTIALS_FILE" ]] || die "Credentials file not found: $CREDENTIALS_FILE" info "Loading credentials from: $CREDENTIALS_FILE" # Parse JSON file OLLAMA_URL=$(grep -oP '"ollama_url"\s*:\s*"\K[^"]+' "$CREDENTIALS_FILE" 2>/dev/null || echo "$OLLAMA_URL") OLLAMA_MODEL=$(grep -oP '"ollama_model"\s*:\s*"\K[^"]+' "$CREDENTIALS_FILE" 2>/dev/null || echo "$OLLAMA_MODEL") EMBEDDING_MODEL=$(grep -oP '"embedding_model"\s*:\s*"\K[^"]+' "$CREDENTIALS_FILE" 2>/dev/null || echo "$EMBEDDING_MODEL") fi # Read current .env file from container info "Reading current configuration..." CURRENT_ENV=$(pct exec "$CTID" -- cat /opt/customer-stack/.env 2>/dev/null || echo "") [[ -n "$CURRENT_ENV" ]] || die "Could not read .env file from container" # Get n8n owner email N8N_EMAIL=$(echo "$CURRENT_ENV" | grep -oP 'N8N_OWNER_EMAIL=\K.*' || echo "admin@userman.de") # Update credentials in n8n if [[ -n "$OLLAMA_URL" ]] || [[ -n "$OLLAMA_MODEL" ]] || [[ -n "$EMBEDDING_MODEL" ]]; then info "Updating n8n credentials..." # Get current values if not specified [[ -z "$OLLAMA_URL" ]] && OLLAMA_URL=$(echo "$CURRENT_ENV" | grep -oP 'OLLAMA_URL=\K.*' || echo "http://192.168.45.3:11434") [[ -z "$OLLAMA_MODEL" ]] && OLLAMA_MODEL="ministral-3:3b" [[ -z "$EMBEDDING_MODEL" ]] && EMBEDDING_MODEL="nomic-embed-text:latest" info "New Ollama URL: $OLLAMA_URL" info "New Ollama Model: $OLLAMA_MODEL" info "New Embedding Model: $EMBEDDING_MODEL" # Login to n8n N8N_PASS=$(echo "$CURRENT_ENV" | grep -oP 'N8N_OWNER_PASSWORD=\K.*' || echo "") [[ -n "$N8N_PASS" ]] || die "Could not determine n8n password" # Update Ollama credential via API pct exec "$CTID" -- bash -c " # Login curl -sS -X POST 'http://127.0.0.1:5678/rest/login' \ -H 'Content-Type: application/json' \ -c /tmp/n8n_update_cookies.txt \ -d '{\"emailOrLdapLoginId\":\"${N8N_EMAIL}\",\"password\":\"${N8N_PASS}\"}' >/dev/null # Get Ollama credential ID CRED_ID=\$(curl -sS -X GET 'http://127.0.0.1:5678/rest/credentials' \ -H 'Content-Type: application/json' \ -b /tmp/n8n_update_cookies.txt | grep -oP '\"type\"\\s*:\\s*\"ollamaApi\".*?\"id\"\\s*:\\s*\"\\K[^\"]+' | head -1) if [[ -n \"\$CRED_ID\" ]]; then # Update credential curl -sS -X PATCH \"http://127.0.0.1:5678/rest/credentials/\$CRED_ID\" \ -H 'Content-Type: application/json' \ -b /tmp/n8n_update_cookies.txt \ -d '{\"data\":{\"baseUrl\":\"${OLLAMA_URL}\"}}' >/dev/null echo \"Ollama credential updated: \$CRED_ID\" else echo \"Ollama credential not found\" fi # Cleanup rm -f /tmp/n8n_update_cookies.txt " || warn "Failed to update Ollama credential in n8n" info "Credentials updated in n8n" fi # Update .env file if needed if [[ -n "$PG_PASSWORD" ]] || [[ -n "$N8N_PASSWORD" ]]; then info "Updating .env file..." # This would require restarting containers, so we'll just update the file # and inform the user to restart if [[ -n "$PG_PASSWORD" ]]; then pct exec "$CTID" -- bash -c "sed -i 's/^PG_PASSWORD=.*/PG_PASSWORD=${PG_PASSWORD}/' /opt/customer-stack/.env" info "PostgreSQL password updated in .env (restart required)" fi if [[ -n "$N8N_PASSWORD" ]]; then pct exec "$CTID" -- bash -c "sed -i 's/^N8N_OWNER_PASSWORD=.*/N8N_OWNER_PASSWORD=${N8N_PASSWORD}/' /opt/customer-stack/.env" info "n8n password updated in .env (restart required)" fi warn "Container restart required for password changes to take effect:" warn " pct exec $CTID -- bash -c 'cd /opt/customer-stack && docker compose restart'" fi info "Credential update completed successfully"