- 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.
257 lines
9.3 KiB
Ruby
257 lines
9.3 KiB
Ruby
# 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
|