Files
Ricardo Monla 160da47f96 [P2606] WebServer NGINX: plan actualizado, ficha nodo, HTTPS operativo
- P2606: Plan v1.1 EN EJECUCIÓN. Fases 1-3 completadas.
- Ficha nodo srvv-nginx-rm.md. P2606 en adn/07_proyectos.md.
- Incluye cambios acumulados de sesiones anteriores.
2026-03-28 12:18:42 -03:00

257 lines
9.3 KiB
Ruby
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# frozen_string_literal: true
require 'optparse'
require_relative '../core/colores'
require_relative '../core/help_formatter'
require_relative '../db/core/bitacora_db'
module ADN
class SubcomandoAmbitos
def initialize(args, logger)
@args = args
@logger = logger
end
def ejecutar
if @args.empty? || ['help', '-h', '--help'].include?(@args[0])
mostrar_ayuda
return
end
subcomando = @args[0]
sub_args = @args[1..-1] || []
case subcomando
when 'listar'
comando_listar(sub_args)
when 'crear'
comando_crear(sub_args)
when 'info'
comando_info(sub_args)
when 'nodos'
comando_nodos(sub_args)
else
puts "#{Color::RED}✗ Subcomando desconocido: '#{subcomando}'#{Color::RESET}"
puts "\n"
mostrar_ayuda
exit 1
end
rescue Interrupt
puts "\n#{Color::YELLOW}⚠ Operación interrumpida por el usuario#{Color::RESET}"
exit 130
rescue => e
@logger.error("Error en operación de ámbitos: #{e.message}")
puts "#{Color::RED}✗ Error: #{e.message}#{Color::RESET}"
exit 1
end
private
def comando_listar(args)
opts = { activo: nil }
parser = OptionParser.new do |opt|
opt.on("--activo", "Mostrar solo ámbitos activos") { opts[:activo] = true }
opt.on("--inactivo", "Mostrar solo ámbitos inactivos") { opts[:activo] = false }
opt.on("-h", "--help", "Mostrar ayuda") do
puts HelpFormatter.generar_help(
titulo: "Listar Ámbitos",
descripcion: "Muestra la lista de ámbitos (agrupadores de nodos).",
uso: HelpFormatter.format_usage("adn ambitos listar", "[OPCIONES]"),
opciones: [
{ names: ["activo"], desc: "Mostrar solo ámbitos activos" },
{ names: ["inactivo"], desc: "Mostrar solo ámbitos inactivos" },
{ names: ["h", "help"], desc: "Mostrar esta ayuda" }
],
ejemplos: [{ cmd: "./adn/tools/run ambitos listar", desc: "Listar todos los ámbitos" }]
)
exit 0
end
end
parsear_argumentos!(parser, args)
puts "#{Color::CYAN}📋 Listando ámbitos...#{Color::RESET}\n\n"
BitacorasDB::BitacoraDB.with_connection do |db|
ambitos = db.list_ambitos(activo: opts[:activo])
if ambitos.empty?
puts "#{Color::YELLOW}⚠ No se encontraron ámbitos.#{Color::RESET}"
return
end
puts "#{Color::BOLD}#{"ID".ljust(5)} #{"Nombre".ljust(20)} #{"Nodos".ljust(7)} #{"Activo".ljust(6)} #{"Padre".ljust(20)}#{Color::RESET}"
puts "#{"─" * 5} #{"─" * 20} #{"─" * 7} #{"─" * 6} #{"─" * 20}"
ambitos.each do |a|
id = a['id'].to_s.ljust(5)
nombre = a['nombre'].to_s.ljust(20)
count = a['count_nodos'].to_s.ljust(7)
activo = (a['activo'] ? '✅' : '❌').ljust(6)
padre = (a['parent_nombre'] || '-').ljust(20)
puts "#{id} #{nombre} #{count} #{activo} #{padre}"
end
puts "\nTotal: #{ambitos.length} ámbitos."
end
end
def comando_crear(args)
opts = { nombre: nil, descripcion: nil, activo: true }
parser = OptionParser.new do |opt|
opt.on("--nombre NOMBRE", "Nombre del ámbito") { |n| opts[:nombre] = n }
opt.on("--descripcion DESC", "Descripción del ámbito") { |d| opts[:descripcion] = d }
opt.on("-h", "--help", "Mostrar ayuda") do
puts HelpFormatter.generar_help(
titulo: "Crear Ámbito",
descripcion: "Genera un nuevo ámbito para agrupar nodos de infraestructura.",
uso: HelpFormatter.format_usage("adn ambitos crear", "--nombre NOMBRE [OPCIONES]"),
opciones: [
{ names: ["nombre NOMBRE"], desc: "Nombre único del ámbito (obligatorio)" },
{ names: ["descripcion DESC"], desc: "Descripción del propósito del ámbito" },
{ names: ["h", "help"], desc: "Mostrar esta ayuda" }
],
ejemplos: [{ cmd: "./adn/tools/run ambitos crear --nombre dtic-Pruebas", desc: "Crear un ámbito de pruebas" }]
)
exit 0
end
end
parsear_argumentos!(parser, args)
unless opts[:nombre]
puts "#{Color::RED}✗ Error: El parámetro --nombre es obligatorio.#{Color::RESET}"
exit 1
end
puts "#{Color::CYAN}📦 Creando ámbito '#{opts[:nombre]}'...#{Color::RESET}"
BitacorasDB::BitacoraDB.with_connection do |db|
begin
ambito = db.create_ambito(nombre: opts[:nombre], descripcion: opts[:descripcion])
puts "#{Color::GREEN}✅ Ámbito creado exitosamente. ID: #{ambito['id']}#{Color::RESET}"
rescue PG::UniqueViolation
puts "#{Color::RED}✗ Error: Ya existe un ámbito con el nombre '#{opts[:nombre]}'.#{Color::RESET}"
exit 1
end
end
end
def comando_info(args)
opts = {}
parser = OptionParser.new do |opt|
opt.on("-h", "--help", "Mostrar ayuda") do
puts HelpFormatter.generar_help(
titulo: "Info de Ámbito",
descripcion: "Muestra información y estadísticas detalladas de un ámbito.",
uso: HelpFormatter.format_usage("adn ambitos info", "<nombre_o_id>"),
opciones: [],
ejemplos: [{ cmd: "./adn/tools/run ambitos info dtic-DASUTEN", desc: "Ver detalles de dtic-DASUTEN" }]
)
exit 0
end
end
parsear_argumentos!(parser, args)
objetivo = args.first
if objetivo.nil? || objetivo.empty?
puts "#{Color::RED}✗ Error: Debes especificar el nombre o ID del ámbito.#{Color::RESET}"
exit 1
end
BitacorasDB::BitacoraDB.with_connection do |db|
ambito = db.get_ambito(objetivo)
if ambito.nil?
puts "#{Color::RED}✗ Error: Ámbito '#{objetivo}' no encontrado.#{Color::RESET}"
exit 1
end
puts "#{Color::CYAN} Info del Ámbito: #{ambito['nombre']}#{Color::RESET}\n\n"
puts " #{Color::BOLD}ID:#{Color::RESET} #{ambito['id']}"
puts " #{Color::BOLD}Nombre:#{Color::RESET} #{ambito['nombre']}"
puts " #{Color::BOLD}Descripción:#{Color::RESET} #{ambito['descripcion'] || '(sin descripción)'}"
puts " #{Color::BOLD}Padre:#{Color::RESET} #{ambito['parent_nombre'] || '(raíz)'}"
puts " #{Color::BOLD}Activo:#{Color::RESET} #{ambito['activo'] ? 'Sí' : 'No'}"
puts " #{Color::BOLD}Nodos:#{Color::RESET} #{ambito['count_nodos']}"
puts ""
end
end
def comando_nodos(args)
opts = {}
parser = OptionParser.new do |opt|
opt.on("-h", "--help", "Mostrar ayuda") do
puts HelpFormatter.generar_help(
titulo: "Nodos de Ámbito",
descripcion: "Lista todos los nodos pertenecientes a un ámbito.",
uso: HelpFormatter.format_usage("adn ambitos nodos", "<nombre_o_id>"),
opciones: [],
ejemplos: [{ cmd: "./adn/tools/run ambitos nodos dtic-DASUTEN", desc: "Ver componentes agrupados bajo dtic-DASUTEN" }]
)
exit 0
end
end
parsear_argumentos!(parser, args)
objetivo = args.first
if objetivo.nil? || objetivo.empty?
puts "#{Color::RED}✗ Error: Debes especificar el nombre o ID del ámbito.#{Color::RESET}"
exit 1
end
BitacorasDB::BitacoraDB.with_connection do |db|
ambito = db.get_ambito(objetivo)
if ambito.nil?
puts "#{Color::RED}✗ Error: Ámbito '#{objetivo}' no encontrado.#{Color::RESET}"
exit 1
end
puts "#{Color::CYAN}🖥️ Nodos del ámbito '#{ambito['nombre']}'...#{Color::RESET}\n\n"
nodos = db.get_nodos_by_ambito(ambito['id'])
if nodos.empty?
puts "#{Color::YELLOW}⚠ Este ámbito no tiene nodos asignados.#{Color::RESET}"
return
end
nodos.each do |n|
tipo = n['tipo'].to_s.ljust(10)
ip = (n['ip'] || '-').ljust(15)
estado = n['activo'] ? "#{Color::GREEN}ON#{Color::RESET}" : "#{Color::RED}OFF#{Color::RESET}"
puts " #{Color::DIM}#{Color::RESET} #{Color::BOLD}#{n['nombre'].to_s.ljust(20)}#{Color::RESET} [#{tipo}] IP: #{ip} (#{estado})"
end
end
end
def mostrar_ayuda
puts HelpFormatter.generar_help(
titulo: "Gestión de Ámbitos (Modelo DB-First)",
descripcion: "Los ámbitos agrupan lógicamente a los nodos correspondientes a áreas organizativas.",
uso: HelpFormatter.format_usage("adn ambitos", "<subcomando> [OPCIONES]"),
opciones: [
{ names: ["h", "help"], desc: "Mostrar esta ayuda" }
],
ejemplos: [
{ cmd: "./adn/tools/run ambitos listar", desc: "Listar ámbitos y cantidad de nodos" },
{ cmd: "./adn/tools/run ambitos info dtic-DIIAA", desc: "Ver detalle del ámbito DIIAA" },
{ cmd: "./adn/tools/run ambitos nodos dtic-DASUTEN", desc: "Listar hipervisores e infraestructura de DASUTEN" }
]
)
end
def parsear_argumentos!(parser, args)
begin
parser.parse!(args)
rescue OptionParser::InvalidOption => e
puts "#{Color::RED}✗ Error: #{e.message}#{Color::RESET}"
puts "\nEjecuta con --help para ver las opciones disponibles."
exit 1
end
end
end
end