372 lines
11 KiB
Ruby
372 lines
11 KiB
Ruby
#!/usr/bin/env ruby
|
|
# frozen_string_literal: true
|
|
|
|
# tools/orquestador/config.rb
|
|
# ============================
|
|
# Archivo de configuración centralizado para los módulos optimizados
|
|
# del orquestador del dashboard P2601
|
|
|
|
module DashboardConfig
|
|
# ==========================================================================
|
|
# CONFIGURACIÓN PRINCIPAL
|
|
# ==========================================================================
|
|
|
|
# Ruta al dashboard principal
|
|
DASHBOARD_PATH = File.expand_path('../../../dashboard/index.html', __dir__)
|
|
|
|
# Directorio de backups
|
|
BACKUPS_DIR = File.expand_path('../../../dashboard/backups', __dir__)
|
|
|
|
# URLs del dashboard
|
|
URLS = {
|
|
production: 'https://ns8.frlr.utn.edu.ar/bitacoras/p2601',
|
|
static: 'https://ns8.frlr.utn.edu.ar/P2601/',
|
|
staging: 'https://ns8.frlr.utn.edu.ar/P2601-staging/'
|
|
}.freeze
|
|
|
|
# ==========================================================================
|
|
# CONFIGURACIÓN DE SINCRONIZACIÓN
|
|
# ==========================================================================
|
|
|
|
SINCRONIZACION = {
|
|
local: {
|
|
dashboard_dir: File.expand_path('../../../dashboard', __dir__),
|
|
index_file: 'index.html',
|
|
backups_dir: BACKUPS_DIR
|
|
},
|
|
production: {
|
|
dashboard_dir: '/var/www/html/P2601',
|
|
index_file: 'index.html',
|
|
backups_dir: '/var/www/html/P2601/backups'
|
|
},
|
|
staging: {
|
|
dashboard_dir: '/var/www/html/P2601-staging',
|
|
index_file: 'index.html',
|
|
backups_dir: '/var/www/html/P2601-staging/backups'
|
|
}
|
|
}.freeze
|
|
|
|
# ==========================================================================
|
|
# CONFIGURACIÓN DE ESTADOS
|
|
# ==========================================================================
|
|
|
|
ESTADOS = {
|
|
'pending' => {
|
|
nombre: 'Pendiente',
|
|
clase: 'pending',
|
|
color: '#eab308',
|
|
descripcion: 'Hito pendiente de iniciar'
|
|
},
|
|
'in-progress' => {
|
|
nombre: 'En Progreso',
|
|
clase: 'in-progress',
|
|
color: '#3b82f6',
|
|
descripcion: 'Hito en ejecución activa'
|
|
},
|
|
'completed' => {
|
|
nombre: 'Completado',
|
|
clase: 'completed',
|
|
color: '#22c55e',
|
|
descripcion: 'Hito finalizado exitosamente'
|
|
},
|
|
'blocked' => {
|
|
nombre: 'Bloqueado',
|
|
clase: 'blocked',
|
|
color: '#ef4444',
|
|
descripcion: 'Hito bloqueado por dependencias u obstáculos'
|
|
},
|
|
'on-hold' => {
|
|
nombre: 'En Espera',
|
|
clase: 'on-hold',
|
|
color: '#8b5cf6',
|
|
descripcion: 'Hito en espera por priorización o recursos'
|
|
}
|
|
}.freeze
|
|
|
|
# ==========================================================================
|
|
# CONFIGURACIÓN DE FASES Y HITOS
|
|
# ==========================================================================
|
|
|
|
# Hitos predefinidos por fase (con nuevo sistema de IDs)
|
|
HITOS_POR_FASE = {
|
|
'fase5' => [
|
|
{
|
|
id: 'f05001',
|
|
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: ['tag-remote', 'tag-phys'],
|
|
esfuerzo: 'Remoto: ~2h',
|
|
estado: 'pending'
|
|
},
|
|
{
|
|
id: 'f05002',
|
|
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: ['tag-remote', 'SQL Agent'],
|
|
esfuerzo: 'Remoto: ~2h',
|
|
estado: 'pending'
|
|
},
|
|
{
|
|
id: 'f05003',
|
|
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: ['tag-remote', 'Herramientas ADN'],
|
|
esfuerzo: 'Remoto: ~3h',
|
|
estado: 'pending'
|
|
},
|
|
{
|
|
id: 'f05004',
|
|
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: ['tag-remote', 'Herramientas ADN', 'Git'],
|
|
esfuerzo: 'Remoto: ~6h',
|
|
estado: 'pending'
|
|
},
|
|
{
|
|
id: 'f05005',
|
|
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: ['tag-phys', 'tag-remote', 'SQL Profiler'],
|
|
esfuerzo: 'Físico: 2h, Remoto: ~2h',
|
|
estado: 'pending'
|
|
}
|
|
]
|
|
}.freeze
|
|
|
|
# ==========================================================================
|
|
# CONFIGURACIÓN DE VALIDACIÓN
|
|
# ==========================================================================
|
|
|
|
# Reglas de validación para IDs de hitos
|
|
ID_HITO_REGEX = /^f\d{5}$/
|
|
|
|
# Estados válidos
|
|
ESTADOS_VALIDOS = ESTADOS.keys.freeze
|
|
|
|
# Fases válidas
|
|
FASES_VALIDAS = HITOS_POR_FASE.keys.freeze
|
|
|
|
# ==========================================================================
|
|
# CONFIGURACIÓN DE LOGGING
|
|
# ==========================================================================
|
|
|
|
LOGGING = {
|
|
nivel: ENV['DEBUG'] == 'true' ? :debug : :info,
|
|
directorio: File.expand_path('../../../logs', __dir__),
|
|
archivo: 'orquestador.log',
|
|
max_tamano: 10 * 1024 * 1024, # 10 MB
|
|
max_archivos: 5
|
|
}.freeze
|
|
|
|
# ==========================================================================
|
|
# CONFIGURACIÓN DE BACKUPS
|
|
# ==========================================================================
|
|
|
|
BACKUP = {
|
|
retencion_dias: 7,
|
|
max_backups: 50,
|
|
comprimir: false,
|
|
incluir_timestamp: true
|
|
}.freeze
|
|
|
|
# ==========================================================================
|
|
# CONFIGURACIÓN DE MÓDULOS
|
|
# ==========================================================================
|
|
|
|
MODULOS = {
|
|
hitos: {
|
|
cache_habilitado: true,
|
|
cache_ttl: 300, # 5 minutos en segundos
|
|
validar_ids: true
|
|
},
|
|
estados: {
|
|
historial_habilitado: true,
|
|
max_historial: 100
|
|
},
|
|
verificacion: {
|
|
niveles: {
|
|
critico: ['estructura'],
|
|
alto: ['hitos', 'timeline'],
|
|
medio: ['estados'],
|
|
bajo: ['metricas']
|
|
}
|
|
},
|
|
vista_previa: {
|
|
modos: {
|
|
resumen: { lineas_max: 100 },
|
|
hitos: { max_hitos: 50 },
|
|
rapido: { compacto: true }
|
|
}
|
|
}
|
|
}.freeze
|
|
|
|
# ==========================================================================
|
|
# MÉTODOS DE UTILIDAD
|
|
# ==========================================================================
|
|
|
|
# Obtener la ruta completa del dashboard
|
|
def self.dashboard_path
|
|
DASHBOARD_PATH
|
|
end
|
|
|
|
# Obtener el directorio de backups
|
|
def self.backups_dir
|
|
BACKUPS_DIR
|
|
end
|
|
|
|
# Obtener URL del dashboard en producción
|
|
def self.production_url
|
|
URLS[:production]
|
|
end
|
|
|
|
# Verificar si el modo debug está activado
|
|
def self.debug?
|
|
ENV['DEBUG'] == 'true'
|
|
end
|
|
|
|
# Obtener configuración de sincronización para un ambiente
|
|
def self.sincronizacion_config(ambiente = :local)
|
|
SINCRONIZACION[ambiente] || SINCRONIZACION[:local]
|
|
end
|
|
|
|
# Obtener información de un estado
|
|
def self.estado_info(estado)
|
|
ESTADOS[estado] || ESTADOS['pending']
|
|
end
|
|
|
|
# Validar un ID de hito
|
|
def self.id_hito_valido?(id)
|
|
id.match?(ID_HITO_REGEX)
|
|
end
|
|
|
|
# Validar un estado
|
|
def self.estado_valido?(estado)
|
|
ESTADOS_VALIDOS.include?(estado)
|
|
end
|
|
|
|
# Validar una fase
|
|
def self.fase_valida?(fase)
|
|
FASES_VALIDAS.include?(fase)
|
|
end
|
|
|
|
# Obtener hitos de una fase
|
|
def self.hitos_por_fase(fase)
|
|
HITOS_POR_FASE[fase] || []
|
|
end
|
|
|
|
# Obtener todas las fases disponibles
|
|
def self.fases_disponibles
|
|
FASES_VALIDAS
|
|
end
|
|
|
|
# Generar un nuevo ID de hito
|
|
def self.generar_id_hito(fase_numero, secuencia)
|
|
"f#{fase_numero.to_s.rjust(2, '0')}#{secuencia.to_s.rjust(3, '0')}"
|
|
end
|
|
|
|
# Parsear un ID de hito
|
|
def self.parsear_id_hito(id)
|
|
match = id.match(/^f(\d{2})(\d{3})$/)
|
|
return nil unless match
|
|
|
|
{
|
|
fase: match[1].to_i,
|
|
secuencia: match[2].to_i,
|
|
id_completo: id
|
|
}
|
|
end
|
|
|
|
# Obtener la ruta del archivo de log
|
|
def self.log_file
|
|
File.join(LOGGING[:directorio], LOGGING[:archivo])
|
|
end
|
|
|
|
# Crear directorios necesarios
|
|
def self.crear_directorios
|
|
dirs = [
|
|
BACKUPS_DIR,
|
|
LOGGING[:directorio],
|
|
File.dirname(DASHBOARD_PATH)
|
|
]
|
|
|
|
dirs.each do |dir|
|
|
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
|
|
end
|
|
end
|
|
|
|
# Cargar configuración desde variables de entorno
|
|
def self.cargar_desde_env
|
|
config = {
|
|
debug: ENV['DEBUG'] == 'true',
|
|
dashboard_path: ENV['DASHBOARD_PATH'] || DASHBOARD_PATH,
|
|
backups_dir: ENV['BACKUPS_DIR'] || BACKUPS_DIR
|
|
}
|
|
|
|
# Sobrescribir configuración de sincronización si está en ENV
|
|
if ENV['PRODUCTION_DIR']
|
|
SINCRONIZACION[:production][:dashboard_dir] = ENV['PRODUCTION_DIR']
|
|
end
|
|
|
|
config
|
|
end
|
|
|
|
# Mostrar configuración actual
|
|
def self.mostrar_configuracion
|
|
puts "⚙️ CONFIGURACIÓN DEL ORQUESTADOR"
|
|
puts "=" * 60
|
|
|
|
puts "📁 RUTAS:"
|
|
puts " • Dashboard: #{DASHBOARD_PATH}"
|
|
puts " • Backups: #{BACKUPS_DIR}"
|
|
puts " • Logs: #{log_file}"
|
|
|
|
puts "\n🌐 URLs:"
|
|
URLS.each do |nombre, url|
|
|
puts " • #{nombre.capitalize}: #{url}"
|
|
end
|
|
|
|
puts "\n🎯 HITOS PREDEFINIDOS:"
|
|
HITOS_POR_FASE.each do |fase, hitos|
|
|
puts " • #{fase}: #{hitos.size} hitos"
|
|
end
|
|
|
|
puts "\n📊 ESTADOS DISPONIBLES:"
|
|
ESTADOS.each do |codigo, info|
|
|
puts " • #{codigo}: #{info[:nombre]} (#{info[:color]})"
|
|
end
|
|
|
|
puts "\n🔧 MÓDULOS CONFIGURADOS:"
|
|
MODULOS.each_key do |modulo|
|
|
puts " • #{modulo}"
|
|
end
|
|
|
|
puts "\n🔍 VALIDACIONES:"
|
|
puts " • Formato ID hito: #{ID_HITO_REGEX}"
|
|
puts " • Estados válidos: #{ESTADOS_VALIDOS.join(', ')}"
|
|
puts " • Fases válidas: #{FASES_VALIDAS.join(', ')}"
|
|
|
|
puts "\n💾 BACKUP:"
|
|
puts " • Retención: #{BACKUP[:retencion_dias]} días"
|
|
puts " • Máximo backups: #{BACKUP[:max_backups]}"
|
|
puts " • Comprimir: #{BACKUP[:comprimir] ? 'Sí' : 'No'}"
|
|
|
|
puts "\n📝 LOGGING:"
|
|
puts " • Nivel: #{LOGGING[:nivel]}"
|
|
puts " • Tamaño máximo: #{LOGGING[:max_tamano] / (1024 * 1024)} MB"
|
|
puts " • Archivos máximos: #{LOGGING[:max_archivos]}"
|
|
|
|
puts "\n✅ Configuración cargada correctamente"
|
|
end
|
|
end
|
|
|
|
# Inicializar directorios al cargar la configuración
|
|
DashboardConfig.crear_directorios
|
|
|
|
# Cargar configuración desde variables de entorno
|
|
DashboardConfig.cargar_desde_env
|
|
|
|
# Mostrar configuración si se ejecuta directamente
|
|
if __FILE__ == $0
|
|
DashboardConfig.mostrar_configuracion
|
|
end
|