#!/bin/bash
# ═══════════════════════════════════════════════════════════════════════════
# SERVICES.SH - Injection automatique des variables d'environnement
# Transforme "supabase: true" → DATABASE_URL, SUPABASE_URL, etc.
# ═══════════════════════════════════════════════════════════════════════════
# ───────────────────────────────────────────────────────────────────────────
# Configuration par environnement
# ───────────────────────────────────────────────────────────────────────────
declare -A SERVICES_PROD=(
# Supabase / PostgreSQL
[DATABASE_URL]="postgresql://postgres:postgres@192.168.1.12:5433/postgres"
[SUPABASE_URL]="http://192.168.1.12:8200"
[SUPABASE_ANON_KEY]="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0"
# Redis
[REDIS_URL]="redis://192.168.1.12:6379"
# Notifications
[NTFY_URL]="http://192.168.1.12:8080"
[APPRISE_URL]="http://192.168.1.12:8000"
[NOTIF_LOGGER_URL]="http://192.168.1.12:5300"
# AI Orchestrator
[ORCHESTRATOR_URL]="http://192.168.1.12:5501"
# Win11 (pour AI tools)
[WIN11_HOST]="192.168.1.30"
[WIN11_USER]="gouro"
[OLLAMA_URL]="http://192.168.1.30:11434"
# Open WebUI (Chat interface)
[OPENWEBUI_URL]="http://192.168.1.12:3001"
# Auth
[AUTH_URL]="http://192.168.1.12:8284"
# Connectors
[CONNECTORS_URL]="http://192.168.1.12:5400"
[BROWSER_CONNECTOR_URL]="http://192.168.1.12:5401"
# YOLO API (image detection)
[YOLO_URL]="http://192.168.1.12:9200"
# Monitoring
[GRAFANA_URL]="http://192.168.1.12:3000"
[PROMETHEUS_URL]="http://192.168.1.12:9090"
[LOKI_URL]="http://192.168.1.12:3100"
# Registry & GitLab
[REGISTRY_URL]="registry.33800.nowhere84.com"
[GITLAB_URL]="https://gitlab.33800.nowhere84.com"
[GITLAB_API_TOKEN]="glpat-yaowLwWBJhXfzJEC8UBC"
# Storage paths
[STOCK_8TO_PATH]="/mnt/stock_8to"
[SERVICES_PATH]="/mnt/stock_8to/33800-stack/services"
)
declare -A SERVICES_DEV=(
# Supabase / PostgreSQL
[DATABASE_URL]="postgresql://postgres:postgres@192.168.1.51:5432/postgres"
[SUPABASE_URL]="http://192.168.1.51:8100"
[SUPABASE_ANON_KEY]="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0"
# Redis
[REDIS_URL]="redis://192.168.1.51:6379"
# Notifications (shared with PROD)
[NTFY_URL]="http://192.168.1.12:8080"
[APPRISE_URL]="http://192.168.1.12:8000"
[NOTIF_LOGGER_URL]="http://192.168.1.12:5300"
# AI Orchestrator (shared with PROD)
[ORCHESTRATOR_URL]="http://192.168.1.12:5501"
# Win11 (shared with PROD)
[WIN11_HOST]="192.168.1.30"
[WIN11_USER]="gouro"
[OLLAMA_URL]="http://192.168.1.30:11434"
# Open WebUI (shared with PROD)
[OPENWEBUI_URL]="http://192.168.1.12:3001"
# Auth (shared with PROD)
[AUTH_URL]="http://192.168.1.12:8284"
# Connectors (shared with PROD)
[CONNECTORS_URL]="http://192.168.1.12:5400"
[BROWSER_CONNECTOR_URL]="http://192.168.1.12:5401"
# YOLO API (shared with PROD)
[YOLO_URL]="http://192.168.1.12:9200"
# Monitoring (shared with PROD)
[GRAFANA_URL]="http://192.168.1.12:3000"
[PROMETHEUS_URL]="http://192.168.1.12:9090"
[LOKI_URL]="http://192.168.1.12:3100"
# Registry & GitLab
[REGISTRY_URL]="registry.33800.nowhere84.com"
[GITLAB_URL]="https://gitlab.33800.nowhere84.com"
[GITLAB_API_TOKEN]="glpat-yaowLwWBJhXfzJEC8UBC"
# Storage paths (DEV)
[STOCK_8TO_PATH]="/mnt/stock_1to"
[SERVICES_PATH]="/mnt/stock_1to/services"
)
# ───────────────────────────────────────────────────────────────────────────
# Mapping service → variables à injecter
# ───────────────────────────────────────────────────────────────────────────
declare -A SERVICE_VARS=(
# Database
[supabase]="DATABASE_URL SUPABASE_URL SUPABASE_ANON_KEY"
[postgres]="DATABASE_URL"
[redis]="REDIS_URL"
# Notifications
[ntfy]="NTFY_URL"
[apprise]="APPRISE_URL"
[notif]="NOTIF_LOGGER_URL"
[notifications]="NTFY_URL APPRISE_URL NOTIF_LOGGER_URL"
# Auth
[auth]="AUTH_URL"
# Connectors
[linkedin]="CONNECTORS_URL BROWSER_CONNECTOR_URL"
[connectors]="CONNECTORS_URL BROWSER_CONNECTOR_URL"
# AI Orchestrator (all AI tools on win11)
[ai]="ORCHESTRATOR_URL WIN11_HOST WIN11_USER"
[orchestrator]="ORCHESTRATOR_URL WIN11_HOST WIN11_USER"
[ollama]="ORCHESTRATOR_URL OLLAMA_URL"
[comfyui]="ORCHESTRATOR_URL"
[fooocus]="ORCHESTRATOR_URL"
[bark]="ORCHESTRATOR_URL"
[musicgen]="ORCHESTRATOR_URL"
[wan21]="ORCHESTRATOR_URL"
[triposr]="ORCHESTRATOR_URL"
[applio]="ORCHESTRATOR_URL"
[facefusion]="ORCHESTRATOR_URL"
[sadtalker]="ORCHESTRATOR_URL"
[whisper]="ORCHESTRATOR_URL"
# Chat
[openwebui]="OPENWEBUI_URL OLLAMA_URL"
[chat]="OPENWEBUI_URL"
# Image processing
[yolo]="YOLO_URL"
# Monitoring
[monitoring]="GRAFANA_URL PROMETHEUS_URL LOKI_URL"
[grafana]="GRAFANA_URL"
[prometheus]="PROMETHEUS_URL"
[loki]="LOKI_URL"
# Infrastructure
[gitlab]="GITLAB_URL GITLAB_API_TOKEN"
[registry]="REGISTRY_URL"
[storage]="STOCK_8TO_PATH SERVICES_PATH"
)
# ───────────────────────────────────────────────────────────────────────────
# Injecter les variables selon les services déclarés
# ───────────────────────────────────────────────────────────────────────────
inject_services() {
local env_file="${1:-${PROJECT_DIR}/.env.deploy}"
local deploy_env="${DEPLOY_ENV:-prod}"
log_step "Injection des variables d'environnement (env: $deploy_env)"
# Sélectionner la config selon l'environnement
local -n services_config
if [[ "$deploy_env" == "prod" ]] || [[ "$deploy_env" == "staging" ]]; then
services_config=SERVICES_PROD
else
services_config=SERVICES_DEV
fi
# Créer/vider le fichier .env
> "$env_file"
# Variables de base
echo "# Auto-generated by smart-deploy.sh" >> "$env_file"
echo "# Env: $deploy_env" >> "$env_file"
echo "# Date: $(date -Iseconds)" >> "$env_file"
echo "" >> "$env_file"
# Parcourir les services déclarés
local injected_vars=""
for service in "${!SERVICE_VARS[@]}"; do
local var_name="CFG_${service}"
local var_value="${!var_name:-false}"
if [[ "$var_value" == "true" ]]; then
log_info " Service activé: $service"
# Injecter les variables associées
for var in ${SERVICE_VARS[$service]}; do
# Éviter les doublons
if [[ ! "$injected_vars" =~ "$var" ]]; then
local value="${services_config[$var]}"
if [[ -n "$value" ]]; then
echo "${var}=${value}" >> "$env_file"
injected_vars="$injected_vars $var"
fi
fi
done
fi
done
# Ajouter NTFY_TOPIC si ntfy activé
if [[ "${CFG_ntfy:-false}" == "true" ]]; then
echo "NTFY_TOPIC=${CFG_name}" >> "$env_file"
fi
# Ajouter le port si défini
if [[ -n "${CFG_port:-}" ]]; then
echo "PORT=${CFG_port}" >> "$env_file"
fi
# Ajouter NODE_ENV
if [[ "$deploy_env" == "prod" ]]; then
echo "NODE_ENV=production" >> "$env_file"
else
echo "NODE_ENV=development" >> "$env_file"
fi
log_success "Variables injectées dans $env_file"
# Afficher le contenu (debug)
if [[ "${DEBUG:-false}" == "true" ]]; then
echo "--- Contenu de $env_file ---"
cat "$env_file"
echo "----------------------------"
fi
}
# ───────────────────────────────────────────────────────────────────────────
# Charger les variables depuis le fichier .env
# ───────────────────────────────────────────────────────────────────────────
load_env_file() {
local env_file="${1:-${PROJECT_DIR}/.env.deploy}"
if [[ -f "$env_file" ]]; then
set -a
source "$env_file"
set +a
log_info "Variables chargées depuis $env_file"
fi
}
# ───────────────────────────────────────────────────────────────────────────
# Injecter les variables personnalisées depuis la section env: du yaml
# Résout les @VAR en utilisant les secrets du fichier de secrets
# ───────────────────────────────────────────────────────────────────────────
inject_custom_env() {
local yaml_file="$1"
local env_file="${2:-${PROJECT_DIR}/.env.deploy}"
local deploy_env="${DEPLOY_ENV:-prod}"
log_step "Injection des variables personnalisées (env: section)"
# Déterminer le fichier de secrets selon l'environnement
local secrets_file
if [[ "$deploy_env" == "dev" ]]; then
secrets_file="${SECRETS_DIR:-/mnt/stock_8to/33800-stack/docker/secrets}/dev.env"
else
secrets_file="${SECRETS_DIR:-/mnt/stock_8to/33800-stack/docker/secrets}/prod.env"
fi
# Charger les secrets en mémoire (associative array)
declare -A SECRETS
if [[ -f "$secrets_file" ]]; then
log_info " Chargement secrets depuis: $secrets_file"
while IFS='=' read -r key value; do
# Ignorer commentaires et lignes vides
[[ "$key" =~ ^[[:space:]]*# ]] && continue
[[ -z "$key" ]] && continue
# Nettoyer la clé
key="${key%%[[:space:]]*}"
# Stocker dans le tableau
SECRETS["$key"]="$value"
done < "$secrets_file"
else
log_warning " Fichier de secrets non trouvé: $secrets_file"
fi
# Parser la section env: du yaml
local in_env_section=false
local env_indent=0
while IFS= read -r line; do
# Calculer l'indentation
local stripped="${line#"${line%%[![:space:]]*}"}"
local indent=$(( ${#line} - ${#stripped} ))
# Ignorer commentaires et lignes vides
[[ "$stripped" =~ ^# ]] && continue
[[ -z "$stripped" ]] && continue
# Détecter début de section env:
if [[ "$stripped" =~ ^env:[[:space:]]*$ ]]; then
in_env_section=true
env_indent=$indent
continue
fi
# Si on est dans la section env:
if $in_env_section; then
# Sortir si on revient au niveau parent ou au même niveau
if [[ $indent -le $env_indent ]] && [[ ! "$stripped" =~ ^[[:space:]] ]]; then
in_env_section=false
continue
fi
# Parser les clés de la section
if [[ "$stripped" =~ ^([A-Z_][A-Z0-9_]*)[[:space:]]*:[[:space:]]*(.*) ]]; then
local key="${BASH_REMATCH[1]}"
local value="${BASH_REMATCH[2]}"
# Nettoyer la valeur
value="${value#\"}"
value="${value%\"}"
value="${value#\'}"
value="${value%\'}"
value="${value%%#*}"
value="${value%"${value##*[![:space:]]}"}"
# Résoudre les @VAR
if [[ "$value" =~ ^@(.+)$ ]]; then
local secret_key="${BASH_REMATCH[1]}"
local secret_value="${SECRETS[$secret_key]:-}"
if [[ -n "$secret_value" ]]; then
log_info " ${key} = @${secret_key} → [résolu]"
echo "${key}=${secret_value}" >> "$env_file"
else
log_warning " ${key} = @${secret_key} → SECRET NON TROUVÉ"
fi
elif [[ -n "$value" ]]; then
log_info " ${key} = ${value}"
echo "${key}=${value}" >> "$env_file"
fi
fi
fi
done < "$yaml_file"
log_success "Variables personnalisées injectées"
}