12 KiB
12 KiB
Ejemplos de Scripts de Automatización para CloudRestoreAS
1. Script de Deployment Completo
# deploy_cloudrestore.ps1
# Script para desplegar CloudRestoreAS en un servidor nuevo
param(
[string]$InstallPath = "C:\CloudRestore",
[string]$InputFolder = "C:\Backups\Entrada",
[string]$ProcessedFolder = "C:\Backups\Procesados",
[string]$SQLServer = "localhost",
[string]$SQLDataFolder = "C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA"
)
Write-Host "Desplegando CloudRestoreAS..." -ForegroundColor Cyan
# Crear directorios
$folders = @($InstallPath, $InputFolder, $ProcessedFolder)
foreach ($folder in $folders) {
if (-not (Test-Path $folder)) {
New-Item -ItemType Directory -Path $folder -Force | Out-Null
Write-Host "✓ Creado: $folder" -ForegroundColor Green
}
}
# Copiar archivos de la aplicación
Copy-Item -Path ".\*" -Destination $InstallPath -Recurse -Force -Exclude @("venv", "build", "dist", "*.log")
# Instalar dependencias
Set-Location $InstallPath
python -m venv venv
.\venv\Scripts\pip.exe install -r requirements.txt
Write-Host "✓ CloudRestoreAS instalado en: $InstallPath" -ForegroundColor Green
2. Configuración Automática de Nodos desde CSV
# import_nodes.ps1
# Importa nodos desde un archivo CSV
param(
[string]$CSVPath = "nodes.csv"
)
# Formato CSV:
# NodeName,DatabaseName,Active,Notes
# BACKUP_VENTAS.ZIP,Ventas_DB,1,Base de datos de ventas
# BACKUP_INVENTARIO.ZIP,Inventario_DB,1,Sistema de inventario
$script = @"
import csv
from app.db.node_repository import NodeRepository
with open('$CSVPath', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
NodeRepository.create(
node_name=row['NodeName'].upper(),
db_name=row['DatabaseName'],
notes=row.get('Notes', '')
)
if row.get('Active', '1') == '0':
NodeRepository.update(row['NodeName'].upper(), active=False)
print(f"Importado: {row['NodeName']} -> {row['DatabaseName']}")
"@
python -c $script
Write-Host "✓ Nodos importados desde $CSVPath" -ForegroundColor Green
3. Monitoreo y Alertas
# monitor_cloudrestore.ps1
# Monitorea el estado de CloudRestoreAS y envía alertas
param(
[string]$EmailTo = "admin@empresa.com",
[string]$EmailFrom = "cloudrestore@empresa.com",
[string]$SMTPServer = "smtp.empresa.com"
)
$script = @"
from app.db.job_repository import JobRepository
from app.db.event_repository import EventRepository
import json
stats = JobRepository.get_stats()
recent_errors = EventRepository.get_all(level='ERROR', limit=10)
result = {
'stats': stats,
'errors': [{'created_at': e.created_at, 'message': e.message} for e in recent_errors]
}
print(json.dumps(result))
"@
$result = python -c $script | ConvertFrom-Json
# Verificar si hay problemas
$shouldAlert = $false
$alertMessage = "CloudRestoreAS - Reporte de Estado`n`n"
if ($result.stats.failed -gt 0) {
$shouldAlert = $true
$alertMessage += "⚠️ Jobs Fallados: $($result.stats.failed)`n"
}
if ($result.errors.Count -gt 0) {
$shouldAlert = $true
$alertMessage += "`nÚltimos Errores:`n"
foreach ($error in $result.errors) {
$alertMessage += " - $($error.created_at): $($error.message)`n"
}
}
$alertMessage += "`nEstadísticas:`n"
$alertMessage += " Total: $($result.stats.total)`n"
$alertMessage += " Completados: $($result.stats.completed)`n"
$alertMessage += " En Cola: $($result.stats.queued)`n"
$alertMessage += " Ejecutando: $($result.stats.running)`n"
if ($shouldAlert) {
# Enviar email
Send-MailMessage -To $EmailTo -From $EmailFrom -Subject "CloudRestoreAS - Alerta" `
-Body $alertMessage -SmtpServer $SMTPServer
Write-Host "⚠️ Alerta enviada" -ForegroundColor Yellow
} else {
Write-Host "✓ Todo OK" -ForegroundColor Green
}
4. Limpieza Automática
# cleanup_old_jobs.ps1
# Limpia jobs antiguos y archivos procesados
param(
[int]$DaysToKeep = 30,
[string]$ProcessedFolder = "C:\Backups\Procesados",
[switch]$CleanDatabase
)
Write-Host "Limpiando archivos antiguos (más de $DaysToKeep días)..." -ForegroundColor Cyan
# Limpiar archivos procesados
$cutoffDate = (Get-Date).AddDays(-$DaysToKeep)
$filesRemoved = 0
Get-ChildItem $ProcessedFolder -Recurse -File | Where-Object {
$_.LastWriteTime -lt $cutoffDate
} | ForEach-Object {
Remove-Item $_.FullName -Force
$filesRemoved++
}
Write-Host "✓ Archivos eliminados: $filesRemoved" -ForegroundColor Green
# Limpiar registros de base de datos (opcional)
if ($CleanDatabase) {
$script = @"
from app.db.database import db
from datetime import datetime, timedelta
cutoff = (datetime.utcnow() - timedelta(days=$DaysToKeep)).isoformat()
# Eliminar job_steps de jobs antiguos completados
db.execute('''
DELETE FROM job_steps
WHERE job_id IN (
SELECT job_id FROM jobs
WHERE status = 'completed' AND created_at < ?
)
''', (cutoff,))
# Eliminar jobs antiguos completados
result = db.execute('''
DELETE FROM jobs
WHERE status = 'completed' AND created_at < ?
''', (cutoff,))
print(f"Jobs eliminados: {result.rowcount}")
"@
$result = python -c $script
Write-Host "✓ $result" -ForegroundColor Green
}
5. Backup y Restore de Configuración
# backup_config.ps1
# Respalda la configuración y base de datos
param(
[string]$BackupPath = "C:\Backups\CloudRestore_Config"
)
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$backupDir = Join-Path $BackupPath $timestamp
New-Item -ItemType Directory -Path $backupDir -Force | Out-Null
# Backup de base de datos SQLite
Copy-Item "data\app.db" "$backupDir\app.db"
# Backup de logs recientes
Copy-Item "logs\*.log" $backupDir -ErrorAction SilentlyContinue
Write-Host "✓ Backup creado en: $backupDir" -ForegroundColor Green
# Comprimir
Compress-Archive -Path $backupDir -DestinationPath "$backupDir.zip"
Remove-Item $backupDir -Recurse -Force
Write-Host "✓ Backup comprimido: $backupDir.zip" -ForegroundColor Green
# restore_config.ps1
# Restaura configuración desde backup
param(
[string]$BackupZip
)
if (-not (Test-Path $BackupZip)) {
Write-Error "Archivo de backup no encontrado: $BackupZip"
exit 1
}
# Extraer
$tempDir = Join-Path $env:TEMP "cloudrestore_restore"
Expand-Archive -Path $BackupZip -DestinationPath $tempDir -Force
# Restaurar base de datos
Copy-Item "$tempDir\app.db" "data\app.db" -Force
Write-Host "✓ Configuración restaurada desde: $BackupZip" -ForegroundColor Green
# Limpiar
Remove-Item $tempDir -Recurse -Force
6. Verificación de Salud del Sistema
# health_check.ps1
# Verifica que todos los componentes estén funcionando
Write-Host "CloudRestoreAS - Health Check" -ForegroundColor Cyan
Write-Host ""
$healthOK = $true
# 1. Verificar carpetas configuradas
$script = @"
from app.db.config_repository import ConfigRepository
import json
config = ConfigRepository.get('app_config', {})
print(json.dumps(config.get('paths', {})))
"@
$paths = python -c $script | ConvertFrom-Json
foreach ($key in $paths.PSObject.Properties.Name) {
$path = $paths.$key
if ($path -and (Test-Path $path)) {
Write-Host "✓ $key : $path" -ForegroundColor Green
} else {
Write-Host "✗ $key : $path (no existe)" -ForegroundColor Red
$healthOK = $false
}
}
# 2. Verificar 7-Zip
$sevenZipPath = $paths.seven_zip_exe
if ($sevenZipPath -and (Test-Path $sevenZipPath)) {
Write-Host "✓ 7-Zip: $sevenZipPath" -ForegroundColor Green
} else {
Write-Host "✗ 7-Zip no configurado" -ForegroundColor Red
$healthOK = $false
}
# 3. Verificar conexión SQL
$scriptSQL = @"
from app.db.config_repository import ConfigRepository
from app.sql.sql_manager import SQLServerManager
from app.utils.crypto import decrypt_password
config = ConfigRepository.get('app_config', {})
sql_config = config.get('sql', {})
manager = SQLServerManager(
server=sql_config.get('server', 'localhost'),
use_windows_auth=sql_config.get('use_windows_auth', True),
username=sql_config.get('username'),
password=decrypt_password(sql_config.get('password_encrypted', '')) if sql_config.get('password_encrypted') else None
)
success, error = manager.test_connection()
print('OK' if success else f'ERROR: {error}')
"@
$sqlResult = python -c $scriptSQL
if ($sqlResult -eq 'OK') {
Write-Host "✓ SQL Server: Conexión OK" -ForegroundColor Green
} else {
Write-Host "✗ SQL Server: $sqlResult" -ForegroundColor Red
$healthOK = $false
}
# 4. Verificar base de datos
$scriptDB = @"
from app.db.database import db
conn = db.get_connection()
cursor = conn.cursor()
cursor.execute("SELECT COUNT(*) FROM jobs")
job_count = cursor.fetchone()[0]
print(job_count)
"@
try {
$jobCount = python -c $scriptDB
Write-Host "✓ Base de datos: $jobCount jobs registrados" -ForegroundColor Green
} catch {
Write-Host "✗ Base de datos: Error de acceso" -ForegroundColor Red
$healthOK = $false
}
Write-Host ""
if ($healthOK) {
Write-Host "✓ Sistema Saludable" -ForegroundColor Green
exit 0
} else {
Write-Host "✗ Se encontraron problemas" -ForegroundColor Red
exit 1
}
7. Generación de Reportes
# generate_report.ps1
# Genera reporte de actividad en HTML
param(
[string]$OutputPath = "report.html",
[int]$Days = 7
)
$script = @"
from app.db.job_repository import JobRepository
from datetime import datetime, timedelta
import json
cutoff = (datetime.utcnow() - timedelta(days=$Days)).isoformat()
jobs = JobRepository.get_all(limit=1000)
recent_jobs = [j for j in jobs if j.created_at >= cutoff]
stats = {
'total': len(recent_jobs),
'completed': len([j for j in recent_jobs if j.status == 'completed']),
'failed': len([j for j in recent_jobs if 'failed' in j.status]),
'avg_time': sum([j.total_ms or 0 for j in recent_jobs if j.status == 'completed']) / max(len([j for j in recent_jobs if j.status == 'completed']), 1)
}
print(json.dumps(stats))
"@
$stats = python -c $script | ConvertFrom-Json
$html = @"
<!DOCTYPE html>
<html>
<head>
<title>CloudRestoreAS - Reporte</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.stat { display: inline-block; margin: 20px; padding: 20px; border: 2px solid #ddd; border-radius: 8px; }
.stat h2 { margin: 0; font-size: 48px; color: #0066cc; }
.stat p { margin: 5px 0 0 0; color: #666; }
</style>
</head>
<body>
<h1>CloudRestoreAS - Reporte de Actividad</h1>
<p>Período: Últimos $Days días</p>
<p>Generado: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')</p>
<div>
<div class="stat">
<h2>$($stats.total)</h2>
<p>Total Jobs</p>
</div>
<div class="stat">
<h2>$($stats.completed)</h2>
<p>Completados</p>
</div>
<div class="stat">
<h2>$($stats.failed)</h2>
<p>Fallados</p>
</div>
<div class="stat">
<h2>$([math]::Round($stats.avg_time / 1000, 1))s</h2>
<p>Tiempo Promedio</p>
</div>
</div>
</body>
</html>
"@
$html | Out-File -FilePath $OutputPath -Encoding UTF8
Write-Host "✓ Reporte generado: $OutputPath" -ForegroundColor Green
# Abrir en navegador
Start-Process $OutputPath
Uso de Scripts con Task Scheduler
# Ejemplo: Programar monitoreo cada hora
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
-Argument "-File C:\CloudRestore\scripts\monitor_cloudrestore.ps1"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Hours 1)
Register-ScheduledTask -TaskName "CloudRestore_Monitor" `
-Action $action -Trigger $trigger -RunLevel Highest
Estos scripts son ejemplos que puedes adaptar a tus necesidades específicas.