[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.
This commit is contained in:
Ricardo Monla
2026-03-28 12:18:42 -03:00
parent 97d9b777b4
commit 160da47f96
78 changed files with 6461 additions and 624 deletions
+121 -5
View File
@@ -21,6 +21,9 @@ module ADN
opt.on("--inactivo", "Crear nodo como inactivo") do
opts[:activo] = false
end
opt.on("--ambito NOMBRE_O_ID", "Ámbito Padre (Opcional)") do |a|
opts[:ambito] = a
end
opt.on("-h", "--help", "Mostrar ayuda") do
puts opt
exit
@@ -45,18 +48,30 @@ module ADN
BitacorasDB::BitacoraDB.with_connection do |db|
begin
ambito_id = nil
if opts[:ambito]
ambito = db.get_ambito(opts[:ambito])
if ambito.nil?
puts "#{Color::RED}✗ Error: Ámbito '#{opts[:ambito]}' no encontrado.#{Color::RESET}"
exit 1
end
ambito_id = ambito['id']
end
nodo = db.create_nodo(
nombre: opts[:nombre],
ip: opts[:ip],
tipo: opts[:tipo],
descripcion: opts[:descripcion],
activo: opts[:activo]
activo: opts[:activo],
ambito_id: ambito_id
)
puts "#{Color::GREEN}✅ Nodo creado exitosamente#{Color::RESET}"
puts ""
puts " #{Color::BOLD}ID:#{Color::RESET} #{nodo['id']}"
puts " #{Color::BOLD}Nombre:#{Color::RESET} #{nodo['nombre']}"
puts " #{Color::BOLD}Ámbito:#{Color::RESET} #{opts[:ambito] ? ambito['nombre'] : '(sin ámbito)'}"
puts " #{Color::BOLD}IP:#{Color::RESET} #{nodo['ip'] || '(sin IP)'}"
puts " #{Color::BOLD}Tipo:#{Color::RESET} #{nodo['tipo']}"
puts " #{Color::BOLD}Activo:#{Color::RESET} #{nodo['activo'] ? 'Sí' : 'No'}"
@@ -86,6 +101,9 @@ module ADN
opt.on("--tipo TIPO", "Filtrar por tipo (servidor, hipervisor, vm, pc)") do |t|
opts[:tipo] = t
end
opt.on("--ambito NOMBRE_O_ID", "Filtrar por ámbito") do |a|
opts[:ambito] = a
end
opt.on("-h", "--help", "Mostrar ayuda") do
puts opt
exit
@@ -103,7 +121,18 @@ module ADN
puts "#{Color::CYAN}🖥️ Listando nodos...#{Color::RESET}"
BitacorasDB::BitacoraDB.with_connection do |db|
nodos = db.list_nodos(activo: opts[:activo], tipo: opts[:tipo], limit: 100)
ambito_id = nil
if opts[:ambito]
ambito = db.get_ambito(opts[:ambito])
if ambito
ambito_id = ambito['id']
else
puts "#{Color::RED}✗ Error: Ámbito '#{opts[:ambito]}' no encontrado.#{Color::RESET}"
exit 1
end
end
nodos = db.list_nodos(activo: opts[:activo], tipo: opts[:tipo], ambito_id: ambito_id, limit: 100)
if nodos.empty?
puts "#{Color::YELLOW}⚠ No se encontraron nodos#{Color::RESET}"
@@ -111,19 +140,21 @@ module ADN
end
puts ""
puts "#{Color::BOLD}#{"ID".ljust(5)} #{"Nombre".ljust(20)} #{"IP".ljust(15)} #{"Tipo".ljust(12)} #{"Activo".ljust(6)} #{"Descripción".ljust(30)}#{Color::RESET}"
puts "#{"" * 5} #{"" * 20} #{"" * 15} #{"" * 12} #{"" * 6} #{"" * 30}"
puts "#{Color::BOLD}#{"ID".ljust(5)} #{"Nombre".ljust(20)} #{"Ámbito".ljust(15)} #{"IP".ljust(15)} #{"Tipo".ljust(12)} #{"Activo".ljust(6)} #{"Descripción".ljust(30)}#{Color::RESET}"
puts "#{"" * 5} #{"" * 20} #{"" * 15} #{"" * 15} #{"" * 12} #{"" * 6} #{"" * 30}"
nodos.each do |n|
id = n['id'].to_s
nombre = n['nombre']
ambito_n = (n['ambito_nombre'] || '-').to_s
ambito_n = ambito_n[0..12] + '...' if ambito_n.length > 15
ip = n['ip'] || '(sin IP)'
tipo = n['tipo']
activo = n['activo'] ? '✅' : '❌'
desc = n['descripcion'] || ''
desc = desc[0..27] + '...' if desc.length > 30
puts "#{id.ljust(5)} #{nombre.ljust(20)} #{ip.ljust(15)} #{tipo.ljust(12)} #{activo.ljust(6)} #{desc.ljust(30)}"
puts "#{id.ljust(5)} #{nombre.ljust(20)} #{ambito_n.ljust(15)} #{ip.ljust(15)} #{tipo.ljust(12)} #{activo.ljust(6)} #{desc.ljust(30)}"
end
puts ""
@@ -135,5 +166,90 @@ module ADN
end
end
# Comando: nodo:actualizar NOMBRE [OPCIONES] - Actualizar nodo existente
def comando_nodo_actualizar(args)
return if args.empty?
nombre = args.shift
opts = { ip: nil, tipo: nil, descripcion: nil, activo: nil, ambito: nil }
parser = OptionParser.new do |opt|
opt.banner = "Uso: adn db nodo:actualizar NOMBRE [OPCIONES]"
opt.on("--ip DIRECCION", "Nueva dirección IP") do |i|
opts[:ip] = i
end
opt.on("--tipo TIPO", "Nuevo tipo (servidor, hipervisor, vm, pc)") do |t|
opts[:tipo] = t
end
opt.on("--descripcion TEXTO", "Nueva descripción") do |d|
opts[:descripcion] = d
end
opt.on("--activo", "Marcar como activo") do
opts[:activo] = true
end
opt.on("--inactivo", "Marcar como inactivo") do
opts[:activo] = false
end
opt.on("--ambito NOMBRE_O_ID", "Nuevo ámbito") do |a|
opts[:ambito] = a
end
opt.on("-h", "--help", "Mostrar ayuda") do
puts opt
exit
end
end
begin
parser.parse!(args)
rescue OptionParser::InvalidOption => e
puts "#{Color::RED}✗ Error: #{e.message}#{Color::RESET}"
puts parser
exit 1
end
puts "#{Color::CYAN}🔄 Actualizando nodo '#{nombre}'...#{Color::RESET}"
BitacorasDB::BitacoraDB.with_connection do |db|
begin
ambito_id = nil
if opts[:ambito]
ambito = db.get_ambito(opts[:ambito])
if ambito.nil?
puts "#{Color::RED}✗ Error: Ámbito '#{opts[:ambito]}' no encontrado.#{Color::RESET}"
exit 1
end
ambito_id = ambito['id']
end
nodo = db.update_nodo(
nombre: nombre,
ip: opts[:ip],
tipo: opts[:tipo],
descripcion: opts[:descripcion],
activo: opts[:activo],
ambito_id: ambito_id
)
if nodo.nil?
puts "#{Color::YELLOW}⚠ No se encontró el nodo '#{nombre}'#{Color::RESET}"
exit 1
end
puts "#{Color::GREEN}✅ Nodo actualizado exitosamente#{Color::RESET}"
puts ""
puts " #{Color::BOLD}ID:#{Color::RESET} #{nodo['id']}"
puts " #{Color::BOLD}Nombre:#{Color::RESET} #{nodo['nombre']}"
puts " #{Color::BOLD}Ámbito:#{Color::RESET} #{ambito_id ? opts[:ambito] : '(sin ámbito)'}"
puts " #{Color::BOLD}IP:#{Color::RESET} #{nodo['ip'] || '(sin IP)'}"
puts " #{Color::BOLD}Tipo:#{Color::RESET} #{nodo['tipo']}"
puts " #{Color::BOLD}Activo:#{Color::RESET} #{nodo['activo'] ? 'Sí' : 'No'}"
puts " #{Color::BOLD}Descripción:#{Color::RESET} #{nodo['descripcion'] || '(sin descripción)'}"
puts " #{Color::BOLD}Actualizado:#{Color::RESET} #{nodo['updated_at']}"
rescue => e
puts "#{Color::RED}✗ Error actualizando nodo: #{e.message}#{Color::RESET}"
end
end
end
end
end