- Configuration complète Stripe pour les 3 environnements (DEV/REC/PROD) * DEV: Clés TEST Pierre (mode test) * REC: Clés TEST Client (mode test) * PROD: Clés LIVE Client (mode live) - Ajout de la gestion des bases de données immeubles/bâtiments * Configuration buildings_database pour DEV/REC/PROD * Service BuildingService pour enrichissement des adresses - Optimisations pages et améliorations ergonomie - Mises à jour des dépendances Composer - Nettoyage des fichiers obsolètes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
285 lines
7.3 KiB
Bash
Executable File
285 lines
7.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
|
||
# =============================================================================
|
||
# SSH Tunnel Management Helper
|
||
# Gère l'ouverture/fermeture des tunnels SSH vers les containers Incus
|
||
# =============================================================================
|
||
|
||
set -euo pipefail
|
||
|
||
# Répertoire du script
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
BAO_ROOT="$(dirname "$SCRIPT_DIR")"
|
||
ENV_FILE="$BAO_ROOT/config/.env"
|
||
|
||
# Couleurs
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[0;33m'
|
||
BLUE='\033[0;34m'
|
||
CYAN='\033[0;36m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Fonctions d'affichage
|
||
log_info() {
|
||
echo -e "${BLUE}ℹ${NC} $*"
|
||
}
|
||
|
||
log_success() {
|
||
echo -e "${GREEN}✓${NC} $*"
|
||
}
|
||
|
||
log_error() {
|
||
echo -e "${RED}✗${NC} $*" >&2
|
||
}
|
||
|
||
log_warning() {
|
||
echo -e "${YELLOW}⚠${NC} $*"
|
||
}
|
||
|
||
# Charge une variable depuis .env
|
||
get_env_var() {
|
||
local key="$1"
|
||
grep "^${key}=" "$ENV_FILE" 2>/dev/null | cut -d'=' -f2- | tr -d ' "'
|
||
}
|
||
|
||
# Vérifie si un tunnel SSH est actif
|
||
is_tunnel_active() {
|
||
local port="$1"
|
||
|
||
# Vérifier si le port est en écoute
|
||
if command -v ss >/dev/null 2>&1; then
|
||
ss -tuln | grep -q ":${port} " && return 0
|
||
elif command -v netstat >/dev/null 2>&1; then
|
||
netstat -tuln | grep -q ":${port} " && return 0
|
||
elif command -v lsof >/dev/null 2>&1; then
|
||
lsof -i ":${port}" -sTCP:LISTEN >/dev/null 2>&1 && return 0
|
||
fi
|
||
|
||
return 1
|
||
}
|
||
|
||
# Trouve le PID du processus SSH pour un tunnel
|
||
get_tunnel_pid() {
|
||
local port="$1"
|
||
|
||
# Chercher le processus SSH qui utilise ce port local
|
||
if command -v lsof >/dev/null 2>&1; then
|
||
lsof -ti ":${port}" -sTCP:LISTEN 2>/dev/null | head -n1
|
||
else
|
||
# Fallback avec ps et grep
|
||
ps aux | grep "ssh.*:${port}:localhost:3306" | grep -v grep | awk '{print $2}' | head -n1
|
||
fi
|
||
}
|
||
|
||
# Ouvre un tunnel SSH
|
||
open_tunnel() {
|
||
local env="${1^^}" # Convertir en majuscules
|
||
|
||
local ssh_host=$(get_env_var "${env}_SSH_HOST")
|
||
local local_port=$(get_env_var "${env}_SSH_PORT_LOCAL")
|
||
local enabled=$(get_env_var "${env}_ENABLED")
|
||
|
||
if [[ "$enabled" != "true" ]]; then
|
||
log_error "Environnement ${env} désactivé dans .env"
|
||
return 1
|
||
fi
|
||
|
||
if [[ -z "$ssh_host" || -z "$local_port" ]]; then
|
||
log_error "Configuration ${env} incomplète dans .env"
|
||
return 1
|
||
fi
|
||
|
||
# Si le port local est 0, on est dans un container avec connexion directe
|
||
if [[ "$local_port" == "0" ]]; then
|
||
# Pas de tunnel nécessaire, connexion directe
|
||
return 0
|
||
fi
|
||
|
||
# Vérifier si le tunnel est déjà actif
|
||
if is_tunnel_active "$local_port"; then
|
||
log_warning "Tunnel ${env} déjà actif sur le port ${local_port}"
|
||
return 0
|
||
fi
|
||
|
||
log_info "Ouverture du tunnel SSH vers ${ssh_host} (port local ${local_port})..."
|
||
|
||
# Créer le tunnel en arrière-plan
|
||
# -N : Ne pas exécuter de commande distante
|
||
# -f : Passer en arrière-plan
|
||
# -o ExitOnForwardFailure=yes : Quitter si le tunnel échoue
|
||
# -o ServerAliveInterval=60 : Garder la connexion active
|
||
ssh -N -f \
|
||
-L "${local_port}:localhost:3306" \
|
||
-o ExitOnForwardFailure=yes \
|
||
-o ServerAliveInterval=60 \
|
||
-o ServerAliveCountMax=3 \
|
||
"$ssh_host" 2>/dev/null
|
||
|
||
# Attendre que le tunnel soit actif
|
||
local max_attempts=10
|
||
local attempt=0
|
||
|
||
while [[ $attempt -lt $max_attempts ]]; do
|
||
if is_tunnel_active "$local_port"; then
|
||
log_success "Tunnel ${env} actif sur le port ${local_port}"
|
||
return 0
|
||
fi
|
||
|
||
sleep 0.5
|
||
((attempt++))
|
||
done
|
||
|
||
log_error "Impossible d'ouvrir le tunnel ${env}"
|
||
return 1
|
||
}
|
||
|
||
# Ferme un tunnel SSH
|
||
close_tunnel() {
|
||
local env="${1^^}"
|
||
|
||
local local_port=$(get_env_var "${env}_SSH_PORT_LOCAL")
|
||
|
||
if [[ -z "$local_port" ]]; then
|
||
log_error "Port local pour ${env} introuvable dans .env"
|
||
return 1
|
||
fi
|
||
|
||
if ! is_tunnel_active "$local_port"; then
|
||
log_warning "Tunnel ${env} non actif sur le port ${local_port}"
|
||
return 0
|
||
fi
|
||
|
||
local pid=$(get_tunnel_pid "$local_port")
|
||
|
||
if [[ -z "$pid" ]]; then
|
||
log_error "Impossible de trouver le PID du tunnel ${env}"
|
||
return 1
|
||
fi
|
||
|
||
log_info "Fermeture du tunnel ${env} (PID ${pid})..."
|
||
|
||
kill "$pid" 2>/dev/null
|
||
|
||
sleep 0.5
|
||
|
||
if ! is_tunnel_active "$local_port"; then
|
||
log_success "Tunnel ${env} fermé"
|
||
return 0
|
||
else
|
||
log_error "Impossible de fermer le tunnel ${env}"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Affiche le statut des tunnels
|
||
status_tunnels() {
|
||
echo -e "\n${CYAN}╔════════════════════════════════════════╗${NC}"
|
||
echo -e "${CYAN}║ État des tunnels SSH ║${NC}"
|
||
echo -e "${CYAN}╚════════════════════════════════════════╝${NC}\n"
|
||
|
||
for env in DVA RCA PRA; do
|
||
local enabled=$(get_env_var "${env}_ENABLED")
|
||
local local_port=$(get_env_var "${env}_SSH_PORT_LOCAL")
|
||
local ssh_host=$(get_env_var "${env}_SSH_HOST")
|
||
|
||
if [[ "$enabled" != "true" ]]; then
|
||
echo -e " ${env}: ${YELLOW}Désactivé${NC}"
|
||
continue
|
||
fi
|
||
|
||
if is_tunnel_active "$local_port"; then
|
||
local pid=$(get_tunnel_pid "$local_port")
|
||
echo -e " ${env}: ${GREEN}✓ Actif${NC} (port ${local_port}, PID ${pid})"
|
||
else
|
||
echo -e " ${env}: ${RED}✗ Inactif${NC} (port ${local_port})"
|
||
fi
|
||
done
|
||
|
||
echo ""
|
||
}
|
||
|
||
# Ferme tous les tunnels
|
||
close_all_tunnels() {
|
||
log_info "Fermeture de tous les tunnels..."
|
||
|
||
for env in DVA RCA PRA; do
|
||
local enabled=$(get_env_var "${env}_ENABLED")
|
||
|
||
if [[ "$enabled" == "true" ]]; then
|
||
close_tunnel "$env" 2>/dev/null || true
|
||
fi
|
||
done
|
||
|
||
log_success "Tous les tunnels ont été fermés"
|
||
}
|
||
|
||
# Usage
|
||
usage() {
|
||
cat <<EOF
|
||
Usage: $(basename "$0") <command> [environment]
|
||
|
||
Commandes:
|
||
open <env> Ouvre un tunnel SSH vers l'environnement
|
||
close <env> Ferme le tunnel SSH
|
||
status Affiche l'état de tous les tunnels
|
||
close-all Ferme tous les tunnels actifs
|
||
|
||
Environnements: DVA, RCA, PRA
|
||
|
||
Exemples:
|
||
$(basename "$0") open dva
|
||
$(basename "$0") close rca
|
||
$(basename "$0") status
|
||
$(basename "$0") close-all
|
||
EOF
|
||
}
|
||
|
||
# Main
|
||
main() {
|
||
if [[ ! -f "$ENV_FILE" ]]; then
|
||
log_error "Fichier .env introuvable: $ENV_FILE"
|
||
log_info "Copiez config/.env.example vers config/.env"
|
||
exit 1
|
||
fi
|
||
|
||
if [[ $# -eq 0 ]]; then
|
||
usage
|
||
exit 0
|
||
fi
|
||
|
||
local command="$1"
|
||
|
||
case "$command" in
|
||
open)
|
||
if [[ $# -lt 2 ]]; then
|
||
log_error "Environnement manquant"
|
||
usage
|
||
exit 1
|
||
fi
|
||
open_tunnel "$2"
|
||
;;
|
||
close)
|
||
if [[ $# -lt 2 ]]; then
|
||
log_error "Environnement manquant"
|
||
usage
|
||
exit 1
|
||
fi
|
||
close_tunnel "$2"
|
||
;;
|
||
status)
|
||
status_tunnels
|
||
;;
|
||
close-all)
|
||
close_all_tunnels
|
||
;;
|
||
*)
|
||
log_error "Commande invalide: $command"
|
||
usage
|
||
exit 1
|
||
;;
|
||
esac
|
||
}
|
||
|
||
main "$@"
|