import os import subprocess import shutil import sys from datetime import datetime # Configurações PASSWORD = "vR7Ag$Pk" TMP_SYNC_BASE = "/tmp/pathfinder_sync" TARGETS = { "nginx": { "src": f"{TMP_SYNC_BASE}/nginx/", "dst": "/etc/nginx", "bak": "/etc/nginx.bak", "test_cmd": ["nginx", "-t"] }, "fail2ban": { "src": f"{TMP_SYNC_BASE}/fail2ban/", "dst": "/etc/fail2ban", "bak": "/etc/fail2ban.bak", "test_cmd": ["fail2ban-server", "-t"] # Apenas teste de config } } def run_sudo(cmd): """Executa comando com sudo -S e retorna (rc, stdout, stderr).""" p = subprocess.Popen(['sudo', '-S'] + cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) out, err = p.communicate(input=PASSWORD + '\n') return p.returncode, out, err def log(msg): print(f"[*] {msg}") def deploy(): log("Iniciando Deploy Seguro Pathfinder...") timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") # 1. Backups preventivos for name, config in TARGETS.items(): log(f"Criando backup de {name}...") run_sudo(['cp', '-rp', config['dst'], f"{config['bak']}_{timestamp}"]) # Mantém também um backup 'fixo' para o rollback rápido do script run_sudo(['rm', '-rf', config['bak']]) run_sudo(['cp', '-rp', config['dst'], config['bak']]) # 2. Aplicação das novas configurações for name, config in TARGETS.items(): if not os.path.exists(config['src']): log(f"Aviso: Fonte {config['src']} não encontrada. Pulando {name}.") continue log(f"Aplicando novas configurações em {name}...") # Copia o conteúdo da pasta temporária para o destino run_sudo(['cp', '-rf', os.path.join(config['src'], '.'), config['dst']]) # 3. Validação Crítica (Nginx) log("Validando configuração do Nginx...") rc, out, err = run_sudo(TARGETS['nginx']['test_cmd']) if rc != 0: log("ERRO DETECTADO NA CONFIGURAÇÃO!") print(f"\nDetalhes do Erro:\n{err}\n") rollback() sys.exit(1) log("Configuração validada com sucesso.") # 4. Reinicialização de Serviços log("Reiniciando serviços...") run_sudo(['systemctl', 'restart', 'nginx']) run_sudo(['systemctl', 'restart', 'fail2ban']) log("Deploy finalizado com sucesso!") def rollback(): log("EXECUTANDO ROLLBACK AUTOMÁTICO...") for name, config in TARGETS.items(): log(f"Restaurando {name} do backup...") run_sudo(['rm', '-rf', config['dst']]) run_sudo(['cp', '-rp', config['bak'], config['dst']]) log("Tentando reiniciar serviços após rollback...") run_sudo(['systemctl', 'restart', 'nginx']) run_sudo(['systemctl', 'restart', 'fail2ban']) log("Rollback concluído. Servidor estabilizado.") if __name__ == "__main__": if os.getuid() == 0: log("Erro: Não execute como root diretamente. O script usa sudo internamente.") sys.exit(1) deploy()