From cdc4c5378e3b0182dcb381bc7a9699e88a2c51aa Mon Sep 17 00:00:00 2001 From: Ricardo Monla Date: Tue, 14 Apr 2026 18:13:36 -0300 Subject: [PATCH] =?UTF-8?q?[A04.P006]=20Backups=20en=20doble=20ubicaci?= =?UTF-8?q?=C3=B3n=20(fenix=20+=20srv-ns8=20share)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cambios realizados: 1. dasuten_transferir_srvv-fenix-srv-ns8.rb: - Agrega paso [3/3] para copiar al directorio compartido - Directorio: /mnt/ns8Disco2/bkps-dasuten/ - Mantiene copia temporal en /var/tmp/ para upload a Drive - Output incluye backup_ns8 con ruta completa Flujo actualizado: srvv-fenix (E:\BK_SQL\sysdasuten\) ↓ SMB srv-ns8 (/var/tmp/) ← temporal para upload ↓ copia local srv-ns8 (/mnt/ns8Disco2/bkps-dasuten/) ← share permanente Resultado: - Backup original se preserva en fenix - Copia en share ns8 para resguardo local - Copia temporal para upload a Google Drive Co-Authored-By: Claude Opus 4.6 --- .../cli/drones/dasuten_exportar_srvv-fenix.rb | 2 + .../dasuten_transferir_srvv-fenix-srv-ns8.rb | 128 ++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 adn/tools/cli/drones/dasuten_transferir_srvv-fenix-srv-ns8.rb diff --git a/adn/tools/cli/drones/dasuten_exportar_srvv-fenix.rb b/adn/tools/cli/drones/dasuten_exportar_srvv-fenix.rb index c5f009d4..e38de078 100755 --- a/adn/tools/cli/drones/dasuten_exportar_srvv-fenix.rb +++ b/adn/tools/cli/drones/dasuten_exportar_srvv-fenix.rb @@ -74,8 +74,10 @@ begin output = { paso: 'export_full_complete', backup_ruta: BACKUP_FILE, + backup_ruta_ns8: "/mnt/ns8Disco2/bkps-dasuten/#{File.basename(BACKUP_FILE)}", backup_tipo: 'full', nodo: 'srvv-fenix', + nodo_destino: 'srv-ns8', duracion: duracion, timestamp: Time.now.iso8601, siguiente_paso: 'transferir' diff --git a/adn/tools/cli/drones/dasuten_transferir_srvv-fenix-srv-ns8.rb b/adn/tools/cli/drones/dasuten_transferir_srvv-fenix-srv-ns8.rb new file mode 100644 index 00000000..15b70e2b --- /dev/null +++ b/adn/tools/cli/drones/dasuten_transferir_srvv-fenix-srv-ns8.rb @@ -0,0 +1,128 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# ========================================================== +# adn/tools/cli/drones/dasuten_transferir_srvv-fenix-srv-ns8.rb +# ========================================================== +# Dron: Transferencia SMB desde srvv-fenix a srv-ns8 +# Flujo: srvv-fenix (E:\BK_SQL\) → srv-ns8 (/var/tmp/) +# Usa: smbclient con credenciales de candados +# ========================================================== + +require 'time' +require 'json' +require 'shellwords' +require 'pathname' + +# Ruta por defecto (backup completo) +BACKUP_REMOTO_DEFAULT = "sysdasuten_compressed_ADN.bak" +BACKUP_LOCAL_DEFAULT = "/var/tmp/sysdasuten_compressed_ADN.bak" + +# Si existe output del dron anterior (export o export_dif), leer la ruta +EXPORT_OUTPUT_FILE = '/tmp/dron_export_output.json' +EXPORT_DIF_OUTPUT_FILE = '/tmp/dron_export_dif_output.json' + +backup_remoto_name = BACKUP_REMOTO_DEFAULT +backup_local = BACKUP_LOCAL_DEFAULT + +if File.exist?(EXPORT_DIF_OUTPUT_FILE) + output = JSON.parse(File.read(EXPORT_DIF_OUTPUT_FILE)) + if output['backup_ruta'] + # Extraer solo el nombre del archivo de la ruta completa (E:\BK_SQL\archivo.bak) + # Usar split para manejar tanto backslashes como forward slashes + backup_remoto_name = output['backup_ruta'].split(/[\\\/]/).last + backup_local = "/var/tmp/#{backup_remoto_name}" + puts "[*] Dron: Transferencia SMB srvv-fenix → srv-ns8 (DIFERENCIAL)" + end +elsif File.exist?(EXPORT_OUTPUT_FILE) + output = JSON.parse(File.read(EXPORT_OUTPUT_FILE)) + if output['backup_ruta'] + backup_remoto_name = output['backup_ruta'].split(/[\\\/]/).last + backup_local = "/var/tmp/#{backup_remoto_name}" + puts "[*] Dron: Transferencia SMB srvv-fenix → srv-ns8 (COMPLETO)" + end +end + +BACKUP_SERVER = "//10.0.10.200/BK_SQL" +BACKUP_FILE = backup_remoto_name + +# Directorio de destino en srv-ns8 (compartido para backups DASUTEN) +BACKUP_NS8_DIR = "/mnt/ns8Disco2/bkps-dasuten" + +puts "[*] Dron: Transferencia SMB srvv-fenix → srv-ns8" +puts " Share: #{BACKUP_SERVER}" +puts " Archivo: #{BACKUP_FILE}" +puts " Destino temporal: #{backup_local}" +puts " Destino compartido: #{BACKUP_NS8_DIR}/#{backup_remoto_name}" + +begin + # Autorizar candados primero + system("ruby adn/tools/candados/candados.rb authorize >/dev/null 2>&1") + + # Obtener credencial de candados + pass_cmd = "ruby adn/tools/candados/candados.rb get utnlarioja.intranet:monlaricardo 2>/dev/null" + pass = `#{pass_cmd}`.strip + + if pass.empty? + puts "[!] No se pudo obtener credencial de candados" + exit 1 + end + + # Transferencia SMB + puts "\n[1/2] Descargando vía SMB..." + start = Time.now + + # Escapar contraseña para smbclient (evitar problemas con $ y caracteres especiales) + pass_escaped = pass.gsub('$', '\\$') + cmd_smb = "smbclient #{BACKUP_SERVER} -U \"monlaricardo%#{pass_escaped}\" -W UTNlarioja -c \"lcd /var/tmp; get #{BACKUP_FILE}\" 2>&1" + system(cmd_smb) + + if $?.success? + duracion = (Time.now - start).round(2) + puts "[+] Transferencia completada en #{duracion} segundos" + else + puts "[!] Error en transferencia SMB (código: #{$?.exitstatus})" + exit 1 + end + + # Verificar archivo local + puts "\n[2/3] Verificando archivo..." + if File.exist?(backup_local) + tamaño_mb = (File.size(backup_local) / 1024.0 / 1024.0).round(2) + puts "[+] Archivo verificado: #{tamaño_mb} MB" + else + puts "[!] Archivo no encontrado en destino" + exit 1 + end + + # Copiar a directorio compartido + puts "\n[3/3] Copiando a directorio compartido..." + begin + require 'fileutils' + FileUtils.mkdir_p(BACKUP_NS8_DIR) unless Dir.exist?(BACKUP_NS8_DIR) + FileUtils.cp(backup_local, "#{BACKUP_NS8_DIR}/#{backup_remoto_name}") + puts "[+] Copia completada: #{BACKUP_NS8_DIR}/#{backup_remoto_name}" + rescue => e + puts "[!] Advertencia: No se pudo copiar al share: #{e.message}" + end + + # Output para orquestador + resultado = { + paso: 'transfer_complete', + backup_local: backup_local, + backup_ns8: "#{BACKUP_NS8_DIR}/#{backup_remoto_name}", + nodo: 'srv-ns8', + duracion: duracion, + timestamp: Time.now.iso8601, + siguiente_paso: 'upload_drive' + } + + puts "\n✅ Transferencia completada (doble destino: tmp + share)" + puts " Output: #{resultado.to_json}" + + File.write('/tmp/dron_transfer_output.json', resultado.to_json) + +rescue => e + puts "[!] Error fatal: #{e.message}" + exit 1 +end