diff --git a/tools/actualizar_dashboard_p2601.rb b/tools/actualizar_dashboard_p2601.rb deleted file mode 100644 index 9b023a1f..00000000 --- a/tools/actualizar_dashboard_p2601.rb +++ /dev/null @@ -1,485 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# tools/actualizar_dashboard_p2601.rb — Herramienta para actualizar dashboard P2601 con hitos adicionales -# ================================================================================ -# Esta herramienta actualiza el dashboard P2601 (dashboard/index.html) agregando -# hitos adicionales propuestos para la fase de implementación final del proyecto DASUTEN. -# -# Características: -# • Lee el dashboard HTML actual -# • Agrega hitos adicionales basados en análisis del proyecto -# • Mantiene la estructura y estilo existentes -# • Integra con herramientas ADN para seguimiento -# • Crea backup del archivo original -# -# Uso: -# ruby tools/actualizar_dashboard_p2601.rb [OPCIONES] -# -# Opciones: -# --dry-run Mostrar cambios sin aplicar -# --backup Crear backup antes de modificar -# --hitos N Agregar solo N hitos (por defecto: todos) -# --categoria CAT Filtrar por categoría (infraestructura, monitoreo, etc.) -# --help Mostrar ayuda - -require 'nokogiri' -require 'fileutils' -require 'optparse' -require 'date' - -class ActualizadorDashboardP2601 - VERSION = "1.0.0" - - # Hitos adicionales propuestos para la fase de implementación - HITOS_ADICIONALES = [ - { - id: "BKP02", - fecha: "Pendiente", - titulo: "Backup Automático de VMs en Proxmox", - descripcion: "Configurar backups automáticos VZDump programados para DC y SQL Server. Establecer retención de 7 días, almacenamiento en NAS/SMB compartido.", - tags: [ - 'Remoto: ~2h', - 'Requiere acceso físico' - ], - estado: "pending", # pending, active, done - categoria: "infraestructura", - prioridad: "alta", - prerequisitos: ["FÍSICO"] - }, - { - id: "MON01", - fecha: "Pendiente", - titulo: "Monitoreo de Recursos del Hipervisor", - descripcion: "Implementar sistema de monitoreo básico para CPU, RAM, almacenamiento y red de srv-dasu. Alertas por email/Telegram para recursos críticos.", - tags: [ - 'Remoto: ~3h', - 'Herramientas ADN' - ], - estado: "pending", - categoria: "monitoreo", - prioridad: "media", - prerequisitos: ["FÍSICO"] - }, - { - id: "DB02", - fecha: "Pendiente", - titulo: "Backup Automático de Base de Datos sysdasuten", - descripcion: "Configurar jobs de SQL Server Agent para backup diario completo y log cada 15 minutos. Verificar restauración periódica en ambiente de pruebas.", - tags: [ - 'Remoto: ~2h', - 'SQL Agent' - ], - estado: "pending", - categoria: "base_datos", - prioridad: "alta", - prerequisitos: ["ADDOM"] - }, - { - id: "SEC01", - fecha: "Pendiente", - titulo: "Auditoría de Seguridad del Dominio", - descripcion: "Revisar y configurar políticas de auditoría en DC. Logs de acceso, cambios en AD, intentos fallidos. Centralización de logs en syslog server.", - tags: [ - 'Remoto: ~4h', - 'Windows Event Log' - ], - estado: "pending", - categoria: "seguridad", - prioridad: "media", - prerequisitos: ["GPO"] - }, - { - id: "DOC01", - fecha: "Pendiente", - titulo: "Documentación Operativa del Sistema", - descripcion: "Crear manual de operaciones: procedimientos de backup/restore, acceso remoto, resolución de problemas comunes, contactos de soporte, diagramas de red.", - tags: [ - 'Remoto: ~6h', - 'Herramientas ADN', - 'Git' - ], - estado: "pending", - categoria: "documentacion", - prioridad: "media", - prerequisitos: ["UAT"] - }, - { - id: "RED01", - fecha: "Pendiente", - titulo: "Optimización de Red y Firewall", - descripcion: "Revisar reglas de firewall en todas las VMs. Optimizar rutas Tailscale. Configurar QoS para tráfico crítico. Documentar reglas de firewall.", - tags: [ - 'Remoto: ~3h', - 'Tailscale', - 'Windows Firewall' - ], - estado: "pending", - categoria: "red", - prioridad: "baja", - prerequisitos: ["NET01"] - }, - { - id: "PERF01", - fecha: "Pendiente", - titulo: "Pruebas de Rendimiento del Sistema", - descripcion: "Realizar pruebas de carga simulada en sistema DASUTEN. Medir tiempos de respuesta, consumo de recursos, identificar cuellos de botella. Generar reporte de performance.", - tags: [ - 'Físico: 2h', - 'Remoto: ~2h', - 'SQL Profiler' - ], - estado: "pending", - categoria: "performance", - prioridad: "media", - prerequisitos: ["CLI"] - }, - { - id: "MIG02", - fecha: "Pendiente", - titulo: "Plan de Migración de Datos Final", - descripcion: "Desarrollar script/procedimiento para migración incremental de datos desde sistema antiguo. Validar integridad de datos migrados. Crear rollback plan.", - tags: [ - 'Remoto: ~8h', - 'SSIS', - 'PowerShell' - ], - estado: "pending", - categoria: "migracion", - prioridad: "alta", - prerequisitos: ["P02.APP"] - } - ].freeze - - def initialize(opciones = {}) - @opciones = opciones - @dashboard_path = '/home/rmonla/Documentos/GitHub/dtic-srv-NS8/dashboard/index.html' - @backup_path = nil - @cambios = [] - @errores = [] - end - - def ejecutar - mostrar_encabezado - - unless validar_entorno - puts "❌ No se puede continuar debido a errores en el entorno." - exit 1 - end - - if @opciones[:dry_run] - puts "🔍 MODO SIMULACIÓN (dry-run) - No se aplicarán cambios reales" - puts "-" * 50 - end - - contenido_original = leer_dashboard - return if contenido_original.nil? - - if @opciones[:backup] && !@opciones[:dry_run] - crear_backup(contenido_original) - end - - hitos_filtrados = filtrar_hitos - puts "📋 Hitos a agregar: #{hitos_filtrados.size} de #{HITOS_ADICIONALES.size} disponibles" - - contenido_actualizado = agregar_hitos_al_dashboard(contenido_original, hitos_filtrados) - - if contenido_actualizado && !@opciones[:dry_run] - guardar_dashboard(contenido_actualizado) - elsif @opciones[:dry_run] - mostrar_cambios_simulados(contenido_actualizado) - end - - mostrar_resumen - rescue => e - puts "❌ Error fatal: #{e.message}" - puts e.backtrace if @opciones[:debug] - exit 1 - end - - private - - def mostrar_encabezado - puts "🔄 ACTUALIZADOR DE DASHBOARD P2601 - v#{VERSION}" - puts "=" * 70 - puts "Proyecto: DASUTEN (P2601)" - puts "Fecha: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}" - puts "Dashboard: #{@dashboard_path}" - puts "" - end - - def validar_entorno - puts "🔍 Validando entorno..." - - # Verificar que el dashboard existe - unless File.exist?(@dashboard_path) - @errores << "Dashboard no encontrado en: #{@dashboard_path}" - puts "❌ #{@errores.last}" - return false - end - - # Verificar permisos de escritura - unless File.writable?(@dashboard_path) - @errores << "Sin permisos de escritura en: #{@dashboard_path}" - puts "❌ #{@errores.last}" - return false - end - - # Verificar que es un archivo HTML válido - contenido = File.read(@dashboard_path, 500) - unless contenido.include?('') || contenido.include?(' e - @errores << "Error leyendo dashboard: #{e.message}" - puts "❌ #{@errores.last}" - nil - end - end - - def crear_backup(contenido) - timestamp = Time.now.strftime('%Y%m%d_%H%M%S') - @backup_path = "#{@dashboard_path}.backup_#{timestamp}" - - puts "💾 Creando backup en: #{@backup_path}" - - begin - File.write(@backup_path, contenido) - puts "✅ Backup creado exitosamente" - rescue => e - @errores << "Error creando backup: #{e.message}" - puts "⚠️ #{@errores.last}" - @backup_path = nil - end - end - - def filtrar_hitos - hitos = HITOS_ADICIONALES.dup - - # Filtrar por categoría si se especificó - if @opciones[:categoria] - categoria = @opciones[:categoria].downcase - hitos.select! { |h| h[:categoria] == categoria } - puts " • Filtrado por categoría: #{categoria} (#{hitos.size} hitos)" - end - - # Limitar número de hitos si se especificó - if @opciones[:hitos] && @opciones[:hitos] > 0 - limite = [@opciones[:hitos], hitos.size].min - hitos = hitos.first(limite) - puts " • Limitado a: #{limite} hitos" - end - - # Ordenar por prioridad (alta -> media -> baja) - orden_prioridad = { 'alta' => 1, 'media' => 2, 'baja' => 3 } - hitos.sort_by! { |h| orden_prioridad[h[:prioridad]] } - - hitos - end - - def agregar_hitos_al_dashboard(contenido, hitos) - puts "✏️ Agregando hitos al dashboard..." - - return contenido if hitos.empty? - - # Buscar el final de la sección de timeline - timeline_end_marker = '' - - unless contenido.include?(timeline_end_marker) - timeline_end_marker = '' - puts "⚠️ Marcador de timeline no encontrado, usando marcador genérico" - end - - # Generar HTML para los nuevos hitos - hitos_html = hitos.map { |hito| generar_html_hito(hito) }.join("\n\n") - - # Insertar los nuevos hitos antes del marcador de fin - nuevo_contenido = contenido.gsub(timeline_end_marker) do |match| - "#{hitos_html}\n\n#{match}" - end - - @cambios = hitos.map { |h| h[:id] } - puts "✅ #{hitos.size} hitos preparados para agregar: #{@cambios.join(', ')}" - - nuevo_contenido - end - - def generar_html_hito(hito) - clase_dot = case hito[:estado] - when 'done' then 'tl-dot done' - when 'active' then 'tl-dot active' - else 'tl-dot pending' - end - - <<~HTML -