[ADN] Commit final DB-First - Actualización completa de documentación, herramientas y componentes
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# adn/tools/core/constants.rb — Definición centralizada de rutas y constantes del ADN
|
||||
# ==============================================================================
|
||||
|
||||
module ADN
|
||||
# El script 'run' está en adn/tools/run, por lo que la raíz es 2 niveles arriba
|
||||
PROJECT_ROOT = File.expand_path('../../..', __dir__)
|
||||
|
||||
NODOS_DIR = File.join(PROJECT_ROOT, 'nodos')
|
||||
PROYECTOS_DIR = File.join(PROJECT_ROOT, 'docs', 'proyectos')
|
||||
BITACORAS_DIR = File.join(PROJECT_ROOT, 'docs', 'bitacoras')
|
||||
LOGS_DIR = File.join(BITACORAS_DIR, '_hist')
|
||||
|
||||
# Directorios de herramientas
|
||||
TOOLS_DIR = File.join(PROJECT_ROOT, 'adn', 'tools')
|
||||
SEGURIDAD_DIR = File.join(TOOLS_DIR, 'seguridad')
|
||||
|
||||
# Bóveda
|
||||
CANDADOS_PATH = File.join(SEGURIDAD_DIR, 'ns8-candados.rb')
|
||||
end
|
||||
@@ -0,0 +1,62 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# adn/tools/core/ejecutor_remoto.rb — Abstracción para ejecución segura via SSH y Candados
|
||||
# ======================================================================================
|
||||
|
||||
require 'open3'
|
||||
require_relative 'constants'
|
||||
|
||||
module ADN
|
||||
class EjecutorRemoto
|
||||
CANDADOS_CMD = ["ruby", ADN::CANDADOS_PATH]
|
||||
|
||||
def self.ejecutar(nodo_info, comando, options = {})
|
||||
# Si es local, ejecutar directamente
|
||||
if nodo_info[:ip] == 'localhost' || nodo_info[:ip] == '127.0.0.1'
|
||||
puts " [LOCAL] > #{comando[0..50]}..." if options[:verbose]
|
||||
output = `#{comando} 2>&1`
|
||||
return { success: $?.success?, output: output }
|
||||
end
|
||||
|
||||
clave = options[:clave] || (nodo_info[:host] == 'srv-dasu' ? 'srv-dasu:rmonla' : 'win_domain')
|
||||
usuario = options[:usuario] || (nodo_info[:so] == :windows ? "monlaricardo@utnlaroja.intranet" : "rmonla")
|
||||
|
||||
# Construir comando SSH base como un array para evitar problemas de shell
|
||||
ssh_cmd = [
|
||||
"sshpass", "-e", "ssh",
|
||||
"-p", (nodo_info[:puerto_ssh] || 22).to_s,
|
||||
"-o", "StrictHostKeyChecking=no",
|
||||
"#{usuario}@#{nodo_info[:ip]}",
|
||||
comando
|
||||
]
|
||||
|
||||
# Comando final encapsulado vía candados
|
||||
# Usamos el modo array de candados: run <clave> <var> <cmd_array>
|
||||
candados_full = CANDADOS_CMD + ["run", clave, "SSHPASS"] + ssh_cmd
|
||||
|
||||
puts " [SSH] #{nodo_info[:nombre]} (#{nodo_info[:ip]}) > #{comando[0..50]}..." if options[:verbose]
|
||||
|
||||
# Usar Open3 para capturar salida limpia
|
||||
stdout, stderr, status = Open3.capture3(*candados_full)
|
||||
|
||||
{ success: status.success?, output: stdout + stderr }
|
||||
end
|
||||
|
||||
# Pipeline para streaming (mejorado)
|
||||
def self.stream_pipeline(src_array, dst_array)
|
||||
begin
|
||||
# Open3.pipeline acepta múltiples arrays de comando
|
||||
statuses = Open3.pipeline(src_array, dst_array)
|
||||
statuses.all?(&:success?)
|
||||
rescue => e
|
||||
puts "Error en pipeline: #{e.message}"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
# Generador de comandos para candados (reutilizable)
|
||||
def self.comando_candados(clave, env_var, comando_array)
|
||||
CANDADOS_CMD + ["run", clave, env_var] + comando_array
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,94 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# adn/tools/core/nodos_info.rb — Utilidades para extracción de metadatos de fichas de nodos
|
||||
# ======================================================================================
|
||||
|
||||
require_relative 'constants'
|
||||
|
||||
module ADN
|
||||
module NodosInfo
|
||||
def self.extraer_metadata(nodo_nombre)
|
||||
ruta = File.join(ADN::NODOS_DIR, "#{nodo_nombre}.md")
|
||||
return nil unless File.exist?(ruta)
|
||||
|
||||
contenido = File.read(ruta, encoding: 'UTF-8')
|
||||
{
|
||||
nombre: nodo_nombre,
|
||||
ip: detectar_ip(contenido),
|
||||
host: detectar_host(contenido),
|
||||
so: detectar_so(contenido),
|
||||
vmid: detectar_vmid(contenido),
|
||||
puerto_ssh: detectar_puerto_ssh(contenido) || 22,
|
||||
usuario: detectar_usuario(contenido)
|
||||
}
|
||||
end
|
||||
|
||||
def self.detectar_usuario(contenido)
|
||||
# | SSH | user@domain@ip:7022 | o user@ip:7022 o user@domain:7022
|
||||
if contenido =~ /(?:SSH|Acceso)\*\*?:?\s*`?([a-zA-Z0-9_\-\.\@]+)/i
|
||||
full = $1
|
||||
if full.include?('@')
|
||||
parts = full.split('@')
|
||||
# Si la última parte es una IP, el usuario es el resto
|
||||
if parts.last =~ /^\d{1,3}(\.\d{1,3}){3}/
|
||||
return parts[0...-1].join('@')
|
||||
else
|
||||
# Probablemente sea user@domain or user@domain:port
|
||||
return full.split(':')[0]
|
||||
end
|
||||
end
|
||||
return full
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def self.detectar_ip(contenido)
|
||||
# | IP / Ubicación | 10.0.10.10 |
|
||||
# | IP | 10.0.100.11/24 |
|
||||
if contenido =~ /\|\s*IP\s*(?:\/\s*Ubicación)?\s*\|\s*`?([\d\.]+)/i
|
||||
return $1
|
||||
end
|
||||
# - **IP**: `10.0.10.200`
|
||||
if contenido =~ /IP\*\*:\s*`?([\d\.]+)/i
|
||||
return $1
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def self.detectar_host(contenido)
|
||||
if contenido =~ /\*\*(?:Padre\/Host|Host Anfitrión|Anfitrión|Host)\*\*\s*[:\|]?\s*`?([a-zA-Z0-9\-]+)`?/i
|
||||
return $1
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def self.detectar_so(contenido)
|
||||
# | Sistema Operativo | ... | o - **Sistema Operativo**: ...
|
||||
if contenido =~ /(?:\||\-)\s*\*\*?(?:Sistema Operativo|SO|OS)\*\*?\s*[:\|]\s*([^\|\n]+)/i
|
||||
so_raw = $1.strip
|
||||
return :windows if so_raw =~ /windows|server|win/i
|
||||
return :linux if so_raw =~ /linux|ubuntu|debian|centos|rocky|proxmox/i
|
||||
end
|
||||
:linux # Default
|
||||
end
|
||||
|
||||
def self.detectar_vmid(contenido)
|
||||
if contenido =~ /(?:VM ID|vmid|VMID)\*\*?:?\s*`?(\d+)`?/i
|
||||
return $1
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def self.detectar_puerto_ssh(contenido)
|
||||
# | SSH | user@ip:7022 |
|
||||
if contenido =~ /(?:SSH|Puerto|Puerto SSH)\*\*?:?\s*.*:(\d+)/i
|
||||
return $1.to_i
|
||||
end
|
||||
# (Puerto 7022)
|
||||
if contenido =~ /\(Puerto\s+(\d+)\)/i
|
||||
return $1.to_i
|
||||
end
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user