#!/bin/bash set -e # Configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONFIG_FILE="$SCRIPT_DIR/sdk_relay/external_nodes.conf" # Couleurs pour l'affichage RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Fonction d'affichage print_info() { echo -e "${BLUE}ℹ️ $1${NC}" } print_success() { echo -e "${GREEN}✅ $1${NC}" } print_warning() { echo -e "${YELLOW}⚠️ $1${NC}" } print_error() { echo -e "${RED}❌ $1${NC}" } # Fonction d'aide show_help() { echo "Usage: $0 [options]" echo "" echo "Commands:" echo " add Ajouter un nœud externe" echo " remove Supprimer un nœud externe" echo " list Lister tous les nœuds externes" echo " test Tester la connectivité d'un nœud" echo " validate Valider une adresse" echo " help Afficher cette aide" echo "" echo "Examples:" echo " $0 add external-relay-1 external-relay-1.example.com:8090" echo " $0 add external-relay-2 192.168.1.100:8090" echo " $0 remove external-relay-1" echo " $0 list" echo " $0 test external-relay-1" } # Fonction pour créer le fichier de configuration s'il n'existe pas create_config_if_not_exists() { if [ ! -f "$CONFIG_FILE" ]; then print_info "Création du fichier de configuration externe..." cat > "$CONFIG_FILE" << EOF # Configuration des nœuds externes pour sdk_relay # Ce fichier permet d'ajouter des nœuds externes sans modifier le code [relays] # Format: relay_id = "address:port" # Exemple: external-relay-1 = "external-relay-1.example.com:8090" [discovery] # Découverte automatique via des nœuds bootstrap auto_discover = true bootstrap_nodes = [ # "bootstrap-1.4nk.net:8090", # "bootstrap-2.4nk.net:8090" ] [security] # Domaines autorisés pour les nœuds externes allowed_domains = [ "*.4nk.net", "*.example.com", "localhost", "127.0.0.1" ] [validation] # Paramètres de validation des nœuds max_connection_timeout = 10 health_check_interval = 300 blacklist_threshold = 5 EOF print_success "Fichier de configuration créé: $CONFIG_FILE" fi } # Fonction pour valider une adresse validate_address() { local address=$1 # Vérifier le format address:port if [[ ! "$address" =~ ^[^:]+:[0-9]+$ ]]; then print_error "Format d'adresse invalide. Utilisez: hostname:port ou ip:port" return 1 fi # Extraire l'hôte et le port local host=$(echo "$address" | cut -d: -f1) local port=$(echo "$address" | cut -d: -f2) # Vérifier que le port est un nombre valide if ! [[ "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then print_error "Port invalide: $port (doit être entre 1 et 65535)" return 1 fi # Vérifier que l'hôte n'est pas vide if [ -z "$host" ]; then print_error "Nom d'hôte vide" return 1 fi print_success "Adresse validée: $address" return 0 } # Fonction pour ajouter un nœud externe add_external_node() { local relay_id=$1 local address=$2 if [ -z "$relay_id" ] || [ -z "$address" ]; then print_error "Usage: $0 add " exit 1 fi print_info "Ajout du nœud externe: $relay_id -> $address" # Valider l'adresse if ! validate_address "$address"; then exit 1 fi # Créer le fichier de configuration s'il n'existe pas create_config_if_not_exists # Vérifier si le relay_id existe déjà if grep -q "^$relay_id = " "$CONFIG_FILE"; then print_warning "Le nœud $relay_id existe déjà. Mise à jour..." # Supprimer l'ancienne entrée sed -i "/^$relay_id = /d" "$CONFIG_FILE" fi # Ajouter le nouveau nœud sed -i "/^\[relays\]$/a $relay_id = \"$address\"" "$CONFIG_FILE" print_success "Nœud externe ajouté avec succès!" print_info "🔄 Redémarrez les relais pour appliquer les changements:" echo " docker-compose restart sdk_relay_1 sdk_relay_2 sdk_relay_3" # Tester la connectivité print_info "🧪 Test de connectivité..." if test_connectivity "$address"; then print_success "Connectivité OK" else print_warning "Connectivité échouée - le nœud sera testé au prochain redémarrage" fi } # Fonction pour supprimer un nœud externe remove_external_node() { local relay_id=$1 if [ -z "$relay_id" ]; then print_error "Usage: $0 remove " exit 1 fi if [ ! -f "$CONFIG_FILE" ]; then print_error "Fichier de configuration non trouvé: $CONFIG_FILE" exit 1 fi if grep -q "^$relay_id = " "$CONFIG_FILE"; then sed -i "/^$relay_id = /d" "$CONFIG_FILE" print_success "Nœud externe $relay_id supprimé" print_info "🔄 Redémarrez les relais pour appliquer les changements:" echo " docker-compose restart sdk_relay_1 sdk_relay_2 sdk_relay_3" else print_warning "Nœud externe $relay_id non trouvé" fi } # Fonction pour lister les nœuds externes list_external_nodes() { if [ ! -f "$CONFIG_FILE" ]; then print_info "Aucun fichier de configuration externe trouvé" return fi print_info "Nœuds externes configurés:" echo "" # Extraire et afficher les nœuds (seulement dans la section [relays]) local nodes=$(sed -n '/^\[relays\]$/,/^\[/p' "$CONFIG_FILE" | grep "^[a-zA-Z0-9_-]* = " | sed 's/ = / -> /' | sed 's/"//g') if [ -z "$nodes" ]; then print_warning "Aucun nœud externe configuré" else echo "$nodes" | while read -r line; do echo " 🔸 $line" done fi echo "" print_info "Configuration: $CONFIG_FILE" } # Fonction pour tester la connectivité test_connectivity() { local address=$1 if [ -z "$address" ]; then print_error "Usage: $0 test ou $0 validate " exit 1 fi # Si c'est un relay_id, récupérer l'adresse if [ -f "$CONFIG_FILE" ] && grep -q "^$address = " "$CONFIG_FILE"; then local actual_address=$(grep "^$address = " "$CONFIG_FILE" | sed 's/.*= "\(.*\)"/\1/') print_info "Test de connectivité pour $address ($actual_address)" address=$actual_address else print_info "Test de connectivité pour $address" fi # Extraire l'hôte et le port local host=$(echo "$address" | cut -d: -f1) local port=$(echo "$address" | cut -d: -f2) print_info "Test de connexion à $host:$port..." # Test de connectivité basique if timeout 5 bash -c "/dev/null; then print_success "✅ Port $port accessible sur $host" # Test WebSocket (simulation) print_info "Test WebSocket..." local ws_response=$(curl -s --connect-timeout 5 -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Sec-WebSocket-Key: test" "http://$host:$port" 2>/dev/null || echo "No response") if [[ "$ws_response" != "No response" ]]; then print_success "✅ WebSocket répond" return 0 else print_warning "⚠️ Pas de réponse WebSocket (normal si pas de client)" return 0 fi else print_error "❌ Impossible de se connecter à $host:$port" return 1 fi } # Fonction pour valider une adresse validate_external_address() { local address=$1 if [ -z "$address" ]; then print_error "Usage: $0 validate " exit 1 fi print_info "Validation de l'adresse: $address" if validate_address "$address"; then print_success "✅ Adresse valide" test_connectivity "$address" else print_error "❌ Adresse invalide" exit 1 fi } # Fonction pour afficher les statistiques show_stats() { if [ ! -f "$CONFIG_FILE" ]; then print_info "Aucun fichier de configuration externe" return fi local total_nodes=$(sed -n '/^\[relays\]$/,/^\[/p' "$CONFIG_FILE" | grep -c "^[a-zA-Z0-9_-]* = " 2>/dev/null || echo "0") print_info "Statistiques:" echo " 📊 Nœuds externes configurés: $total_nodes" echo " 📁 Fichier de configuration: $CONFIG_FILE" if [ -f "$CONFIG_FILE" ]; then local last_modified=$(stat -c %y "$CONFIG_FILE" 2>/dev/null || echo "N/A") echo " 📅 Dernière modification: $last_modified" fi } # Menu principal case "${1:-help}" in "add") add_external_node "$2" "$3" ;; "remove") remove_external_node "$2" ;; "list") list_external_nodes show_stats ;; "test") test_connectivity "$2" ;; "validate") validate_external_address "$2" ;; "help"|"--help"|"-h") show_help ;; *) print_error "Commande inconnue: $1" echo "" show_help exit 1 ;; esac