[A04.P005] Extraído módulo común DasuExecutor para eliminar código repetido
Problema: 6 drones repetían el mismo patrón de ejecución remota: - Base64 encoding de scripts PowerShell - SSH vía srv-dasu con sshpass - Lectura de JSON output desde dasu-sql4 - Verificación de archivos en fenix vía xp_cmdshell Solución: adn/tools/cli/drones/lib/dasu_executor.rb Funciones del módulo: - execute_ps_on_dasu(ps_script) → ejecuta PowerShell en dasu-sql4 - read_json_from_dasu(path) → lee JSON output - execute_ps_with_json_output(ps_script) → combina ambas - execute_ps_on_fenix(client, ps_script) → PowerShell en fenix - file_exists_on_fenix?(client, path) → verifica existencia - get_file_info_on_fenix(client, path) → info completa de archivo Drones refactorizados (líneas ahorradas): - dasuten_restaurar_dasu-sql4.rb: 200 → 95 líneas (-52%) - dasuten_restaurar_diferencial_dasu-sql4.rb: 207 → 100 líneas (-52%) - dasuten_download_drive-dasu-sql4.rb: 269 → 130 líneas (-52%) - dasuten_verificar-integridad_dasu-sql4.rb: 182 → 85 líneas (-53%) - dasuten_exportar_srvv-fenix.rb: usa módulo para verificación - dasuten_exportar_diferencial_srvv-fenix.rb: usa módulo para verificación Beneficio: Si se modifica el patrón SSH/PowerShell, se cambia en 1 solo lugar.
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
# ==========================================================
|
||||
# adn/tools/cli/drones/dasuten_restaurar_diferencial_dasu-sql4.rb
|
||||
# ==========================================================
|
||||
# Dron: Restaurar backup DIFERENCIAL en dasu-sql4
|
||||
# Flujo: RESTORE DATABASE ... WITH DIFFERENTIAL (sobre BD existente)
|
||||
# Entrada: Backup diferencial en F:\BACKUP\
|
||||
# Salida: differential_restore_complete
|
||||
# ==========================================================
|
||||
|
||||
require 'time'
|
||||
require 'json'
|
||||
require_relative 'lib/dasu_executor'
|
||||
|
||||
JSON_PATH = 'C:\temp\dron_restore_dif_output.json'
|
||||
|
||||
puts "[*] Dron: Restaurar backup DIFERENCIAL DASUTEN"
|
||||
puts " Nodo: dasu-sql4"
|
||||
puts " Backup: sysdasuten_DIF_*.bak (más reciente)"
|
||||
puts " Tipo: DIFFERENTIAL (aplica cambios sobre BD existente)"
|
||||
|
||||
# PowerShell script para restore diferencial
|
||||
ps_script = <<~'PSCMD'.strip
|
||||
$ErrorActionPreference = "Stop"
|
||||
$JSON_PATH = "C:\temp\dron_restore_dif_output.json"
|
||||
|
||||
$null = New-Item -ItemType Directory -Force -Path "C:\temp"
|
||||
|
||||
Write-Host "[1/3] Buscando backup diferencial más reciente..."
|
||||
$backupFile = Get-ChildItem "F:\BACKUP\sysdasuten_DIF_*.bak" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
|
||||
if (-not $backupFile) {
|
||||
Write-Host "[!] No se encontró backup diferencial en F:\BACKUP\"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$LOCAL_BACKUP = $backupFile.FullName
|
||||
Write-Host " Archivo: $LOCAL_BACKUP"
|
||||
Write-Host " Tamaño: $([math]::Round($backupFile.Length / 1MB, 2)) MB"
|
||||
|
||||
$sqlcmd = "C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\sqlcmd.exe"
|
||||
|
||||
Write-Host "`n[2/3] Ejecutando RESTORE DATABASE ... WITH DIFFERENTIAL..."
|
||||
$start = Get-Date
|
||||
|
||||
$restoreSql = @"
|
||||
RESTORE DATABASE sysdasuten
|
||||
FROM DISK = '$LOCAL_BACKUP'
|
||||
WITH NORECOVERY, REPLACE
|
||||
"@
|
||||
|
||||
Write-Host " SQL: $restoreSql"
|
||||
|
||||
$restoreOutput = & $sqlcmd -S localhost -Q $restoreSql 2>&1
|
||||
$exitoRestore = $LASTEXITCODE -eq 0
|
||||
$duracionRestore = [math]::Round((New-TimeSpan -Start $start -End (Get-Date)).TotalSeconds, 2)
|
||||
|
||||
if (-not $exitoRestore) {
|
||||
Write-Host "[!] Error en restore:"
|
||||
Write-Host $restoreOutput
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "[+] Restore diferencial completado en $duracionRestore segundos"
|
||||
|
||||
Write-Host "`n[3/3] Poniendo base de datos ONLINE..."
|
||||
|
||||
$recoverySql = "RESTORE DATABASE sysdasuten WITH RECOVERY"
|
||||
$recoveryOutput = & $sqlcmd -S localhost -Q $recoverySql 2>&1
|
||||
$exitoRecovery = $LASTEXITCODE -eq 0
|
||||
$duracionRecovery = [math]::Round((New-TimeSpan -Start (Get-Date) -End (Get-Date)).TotalSeconds, 2)
|
||||
|
||||
if ($exitoRecovery) {
|
||||
Write-Host "[+] Base de datos ONLINE"
|
||||
} else {
|
||||
Write-Host "[!] Error en recovery:"
|
||||
Write-Host $recoveryOutput
|
||||
exit 1
|
||||
}
|
||||
|
||||
$duracionTotal = [math]::Round($duracionRestore + $duracionRecovery, 2)
|
||||
|
||||
$res = @{
|
||||
paso = "differential_restore_complete"
|
||||
backup_ruta = $LOCAL_BACKUP
|
||||
backup_tipo = "differential"
|
||||
nodo = "dasu-sql4"
|
||||
duracion_total = $duracionTotal
|
||||
duracion_restore = $duracionRestore
|
||||
duracion_recovery = $duracionRecovery
|
||||
estado_integridad = "PENDING_CHECKDB"
|
||||
timestamp = (Get-Date -Format "o")
|
||||
siguiente_paso = "verificar_integridad"
|
||||
}
|
||||
|
||||
Write-Host "`n✅ Restauración diferencial completada"
|
||||
Write-Host " Estado: BD ONLINE"
|
||||
Write-Host " Output: $($res | ConvertTo-Json -Compress)"
|
||||
|
||||
$res | ConvertTo-Json | Out-File -FilePath $JSON_PATH -Encoding utf8
|
||||
PSCMD
|
||||
|
||||
puts "\n[1/2] Ejecutando restore diferencial en dasu-sql4..."
|
||||
DasuExecutor.execute_ps_on_dasu(ps_script, output_path: JSON_PATH)
|
||||
|
||||
puts "\n[2/2] Leyendo output JSON..."
|
||||
resultado = DasuExecutor.read_json_from_dasu(JSON_PATH)
|
||||
|
||||
puts " Output: #{resultado.to_json}"
|
||||
|
||||
puts "\n✅ Restauración diferencial completada"
|
||||
puts " Backup: #{resultado['backup_ruta']}"
|
||||
puts " Estado: #{resultado['estado_integridad']}"
|
||||
puts " Duración total: #{resultado['duracion_total']}s"
|
||||
|
||||
File.write('/tmp/dron_restore_dif_output.json', resultado.to_json)
|
||||
puts " JSON guardado en: /tmp/dron_restore_dif_output.json"
|
||||
Reference in New Issue
Block a user