[RFC-ADN-01] Normalizar nomenclatura de proyectos

- Directorios: PascalCase (p2601_dasuten → P2601_Dasuten)
- Planes: numeración pura (P2601_6.1.A → P2601.06.01)
- Sin caracteres especiales en nombres de archivo
- 07_proyectos.md: convención RFC-ADN-01 integrada, P2604/P2605 agregados
- evento:listar: nueva opción --detalle para descripciones completas
This commit is contained in:
Ricardo Monla
2026-03-16 15:15:53 -03:00
parent f608924c6a
commit ba5c65e2a4
33 changed files with 883 additions and 390 deletions
+53 -10
View File
@@ -10,13 +10,54 @@ Un **Proyecto** es un esfuerzo coordinado que agrupa múltiples tareas, nodos y
- Un **Nodo** (infraestructura estática, snapshot), - Un **Nodo** (infraestructura estática, snapshot),
- Una **Bitácora** (registro diario, efímero), - Una **Bitácora** (registro diario, efímero),
Un Proyecto tiene **alcance temporal definido** y **visibilidad gerárquica**: las partes jerárquicas (superiores, coordinadores) pueden consultar su avance de forma asíncrona, típicamente a través de un dashboard web. Un Proyecto tiene **alcance temporal definido** y **visibilidad jerárquica**: las partes jerárquicas (superiores, coordinadores) pueden consultar su avance de forma asíncrona, típicamente a través de un dashboard web.
## 2. Identificación ## 2. Identificación (RFC-ADN-01)
- **Código**: Alfanumérico con prefijo `P` (ej: `P2601`). ### Código de Proyecto
- **Ubicación**: `proyectos/<código>_<nombre>.md` (ej: `proyectos/P2601_dasuten.md`).
- **Referencia en Bitácoras**: Los hitos que pertenecen a un proyecto deben referenciar su código en la descripción. ```
PYYNN_Tema
```
| Elemento | Significado | Ejemplo |
| :------- | :---------- | :------ |
| `P` | Prefijo fijo | `P` |
| `YY` | Año de creación (2 dígitos) | `26` |
| `NN` | Número correlativo | `01` |
| `Tema` | Nombre corto (PascalCase) | `Dasuten` |
**Ejemplo:** `P2601_Dasuten` → Proyecto 01, año 2026, tema Dasuten.
### Secciones y Sub-secciones
```
PYYNN.SS.ss_Tema.md
```
| Elemento | Significado | Ejemplo |
| :------- | :---------- | :------ |
| `PYYNN` | ID del proyecto | `P2601` |
| `SS` | Sección (2 dígitos) | `06` |
| `ss` | Subsección (2 dígitos) | `01` |
| `Tema` | Nombre corto (guiones) | `Red-SrvDasu` |
**Ejemplo:** `P2601.06.01_Red-SrvDasu.md` → P2601, sección 06, sub 01, tema Red del servidor Dasu.
### Directorio del Proyecto
```
docs/proy/PYYNN_Tema/
├── README.md ← Manifiesto (o PYYNN_Tema.md)
├── plan/ ← Planes de ejecución
│ └── PYYNN.SS.ss_Tema.md
└── _hist/ ← Archivo histórico
```
**Reglas de nomenclatura:**
- Directorios: `PascalCase` con guión bajo (`P2601_Dasuten`)
- Archivos de plan: Numeración pura, guiones en tema (`P2601.06.01_Red-SrvDasu.md`)
- Sin caracteres especiales (`:`, espacios) en nombres de archivo
## 3. Formato de Manifiesto ## 3. Formato de Manifiesto
@@ -30,8 +71,8 @@ Cada proyecto debe tener un archivo manifiesto con las siguientes secciones:
| **Nombre** | Nombre descriptivo del proyecto. | | **Nombre** | Nombre descriptivo del proyecto. |
| **Objetivo** | Para qué existe, qué problema resuelve. | | **Objetivo** | Para qué existe, qué problema resuelve. |
| **Stakeholders** | Quién consulta/supervisa el avance (cargo, relación). | | **Stakeholders** | Quién consulta/supervisa el avance (cargo, relación). |
| **Topología y Red** | Contexto espacial: subredes en uso, hypervisors anfitriones, aislamiento NAT y reglas de ruteo/VPN necesarias para acceder al entorno. | | **Topología y Red** | Contexto espacial: subredes, hypervisors, aislamiento NAT y reglas de ruteo/VPN. |
| **Nodos Involucrados** | Qué infraestructura participa (links a `nodos/`). Debe categorizarse en **Nodos Exclusivos** (Core) y **Nodos de Soporte/Infraestructura**. | | **Nodos Involucrados** | Qué infraestructura participa (links a `nodos/`). Categorizar en **Core** y **Soporte**. |
| **Herramientas** | Software, scripts y servicios utilizados. | | **Herramientas** | Software, scripts y servicios utilizados. |
| **Hitos Clave** | Timeline de alto nivel con estados y fechas. | | **Hitos Clave** | Timeline de alto nivel con estados y fechas. |
| **Referencias** | Links a bitácoras, nodos, documentos técnicos. | | **Referencias** | Links a bitácoras, nodos, documentos técnicos. |
@@ -64,6 +105,8 @@ Los proyectos son el **tejido conectivo** que une nodos y bitácoras en un prop
| Código | Nombre | Estado | Manifiesto | | Código | Nombre | Estado | Manifiesto |
| :--- | :--- | :---: | :--- | | :--- | :--- | :---: | :--- |
| P2601 | Sistema DASUTEN | ⏳ | [P2601_dasuten.md](../proyectos/P2601_dasuten.md) | | P2601 | Sistema DASUTEN | ⏳ | [P2601_Dasuten](../docs/proy/P2601_Dasuten/P2601_dasuten.md) |
| P2602 | Backups DTIC | ⏳ | [P2602_backups.md](../proyectos/P2602_backups.md) | | P2602 | Backups DTIC | ⏳ | [P2602_Backups](../docs/proy/P2602_Backups/P2602_backups.md) |
| P2603 | Sistema de Bitácoras | ⏳ | [P2603_bitacoras.md](../proyectos/P2603_bitacoras.md) | | P2603 | Sistema de Bitácoras | ⏳ | [P2603_Bitacoras](../docs/proy/P2603_Bitacoras/P2603_bitacoras.md) |
| P2604 | Mejoras ADN | ⏳ | [P2604_Mejoras-ADN](../docs/proy/P2604_Mejoras-ADN/P2604_mejoras_ADN.md) |
| P2605 | Bitácoras Web | ⏳ | [P2605_Bitacoras-Web](../docs/proy/P2605_Bitacoras-Web/P2605_Migracion_Solo_Bitacoras_Web.md) |
+17 -11
View File
@@ -47,11 +47,11 @@
### Flujo de Trabajo DB-First ### Flujo de Trabajo DB-First
1. **Iniciar jornada**: `./adn/tools/run jornada iniciar [modo] [HH:MM]` (registra en DB) 1. **Iniciar jornada**: `./adn/tools/run jornada iniciar [modo] [HH:MM]` (registra en DB)
2. **Registrar actividad**: `./adn/tools/run db evento:crear [opciones]` (crea entrada en DB) 2. **Registrar actividad**: `./adn/tools/run db evento:crear [opciones]` (estado y modo se calculan automáticamente)
3. **Desarrollar componente Ruby**: Seguir principios "Menos es Más" (atómico, reutilizable) 3. **Desarrollar componente Ruby**: Seguir principios "Menos es Más" (atómico, reutilizable)
4. **Operaciones DB**: Usar `./adn/tools/run db` para todas las operaciones (listar, actualizar, eliminar) 4. **Operaciones DB**: Usar `./adn/tools/run db` para todas las operaciones (listar, actualizar, eliminar)
5. **Registrar finalización**: `./adn/tools/run db evento:actualizar <ID> --fin HH:MM --estado completado` 5. **Registrar finalización**: `./adn/tools/run db evento:actualizar <ID> --fin HH:MM` (estado se calcula automáticamente)
6. **Verificar en Web**: Acceder a `http://localhost:5174` para visualizar bitácora actualizada 6. **Verificar en Web**: Acceder a `http://localhost:5174` - La bitácora se actualiza automáticamente cada 30s o al recuperar el foco
7. **Resguardar cambios**: Commit y push con formato `[Categoría] Descripción` 7. **Resguardar cambios**: Commit y push con formato `[Categoría] Descripción`
### Subcomandos DB Disponibles ### Subcomandos DB Disponibles
@@ -60,9 +60,12 @@
./adn/tools/run db salud:bd ./adn/tools/run db salud:bd
# Gestión de eventos (entradas cronológicas) # Gestión de eventos (entradas cronológicas)
./adn/tools/run db evento:crear --nodo <nombre> --titulo "Título" --inicio HH:MM # Estado y modo se calculan automáticamente:
# - Estado: si tiene --fin → ✅, si no → ⏳
# - Modo: si no se especifica, se obtiene desde la última jornada del día
./adn/tools/run db evento:crear --nodo <nombre> --descripcion "Texto" --inicio HH:MM [--fin HH:MM] [--modo P|R]
./adn/tools/run db evento:listar [--desde FECHA] [--hasta FECHA] [--nodo NODO] ./adn/tools/run db evento:listar [--desde FECHA] [--hasta FECHA] [--nodo NODO]
./adn/tools/run db evento:actualizar <ID> [--fin HH:MM] [--estado ESTADO] ./adn/tools/run db evento:actualizar <ID> [--fin HH:MM] # Estado se calcula automáticamente
./adn/tools/run db evento:eliminar <ID> ./adn/tools/run db evento:eliminar <ID>
# Gestión de bitácoras # Gestión de bitácoras
@@ -166,9 +169,9 @@ referencia canónica y exclusiva de las directivas que un agente IA debe seguir.
| `db salud:bd` | Verificar conexión y estado de PostgreSQL | DB-First | | `db salud:bd` | Verificar conexión y estado de PostgreSQL | DB-First |
| `db bitacora:crear` | Crear nueva bitácora diaria en DB | DB-First | | `db bitacora:crear` | Crear nueva bitácora diaria en DB | DB-First |
| `db bitacora:listar` | Listar bitácoras existentes desde DB | DB-First | | `db bitacora:listar` | Listar bitácoras existentes desde DB | DB-First |
| `db evento:crear` | Crear nueva entrada cronológica (I-F-D-E) | DB-First | | `db evento:crear` | Crear entrada (estado y modo se calculan auto.) | DB-First |
| `db evento:listar` | Listar entradas con filtros desde DB | DB-First | | `db evento:listar` | Listar entradas con filtros desde DB | DB-First |
| `db evento:actualizar` | Actualizar una entrada existente en DB | DB-First | | `db evento:actualizar` | Actualizar entrada (estado auto. si --fin) | DB-First |
| `db evento:eliminar` | Eliminar una entrada existente por ID de DB | DB-First | | `db evento:eliminar` | Eliminar una entrada existente por ID de DB | DB-First |
| `db nodo:crear` | Crear nuevo nodo en DB | DB-First | | `db nodo:crear` | Crear nuevo nodo en DB | DB-First |
| `db nodo:listar` | Listar nodos desde DB | DB-First | | `db nodo:listar` | Listar nodos desde DB | DB-First |
@@ -184,14 +187,17 @@ referencia canónica y exclusiva de las directivas que un agente IA debe seguir.
# 1. INICIO DE JORNADA (registra en DB) # 1. INICIO DE JORNADA (registra en DB)
./adn/tools/run jornada iniciar presencial 08:00 ./adn/tools/run jornada iniciar presencial 08:00
# 2. REGISTRAR ACTIVIDAD DE DESARROLLO RUBY (DB-First) # 2. REGISTRAR ACTIVIDAD (estado y modo se calculan automáticamente)
./adn/tools/run db evento:crear --nodo srv-ns8 --titulo "Desarrollo componente Ruby: hook pre-commit mejorado" --inicio 09:00 --descripcion "Mejora del hook pre-commit para mayor robustez y aplicación de principios ADN" ./adn/tools/run db evento:crear --nodo srv-ns8 --descripcion "Mejora del hook pre-commit" --inicio 09:00
# 2a. Con hora de fin (estado será ✅ automáticamente)
./adn/tools/run db evento:crear --nodo srv-ns8 --descripcion "Tarea completada" --inicio 09:00 --fin 10:00
# 3. LISTAR ACTIVIDADES DEL DÍA (consulta DB) # 3. LISTAR ACTIVIDADES DEL DÍA (consulta DB)
./adn/tools/run db evento:listar --desde $(date +%Y-%m-%d) ./adn/tools/run db evento:listar --desde $(date +%Y-%m-%d)
# 4. ACTUALIZAR ENTRADA AL FINALIZAR (DB-First) # 4. ACTUALIZAR ENTRADA AL FINALIZAR (estado se calcula desde --fin)
./adn/tools/run db evento:actualizar <ID> --fin 12:30 --estado completado ./adn/tools/run db evento:actualizar <ID> --fin 12:30
# 5. CERRAR JORNADA (registra en DB) # 5. CERRAR JORNADA (registra en DB)
./adn/tools/run jornada cerrar remoto 18:00 ./adn/tools/run jornada cerrar remoto 18:00
+79 -24
View File
@@ -57,6 +57,12 @@ module ADN
exit 1 exit 1
end end
# Obtener modo desde jornada actual si no se especifica
modo_resuelto = opts[:modo]
if modo_resuelto.nil?
puts "#{Color::DIM} Modo no especificado, buscando jornada actual...#{Color::RESET}"
end
puts "#{Color::CYAN}📝 Creando nueva entrada...#{Color::RESET}" puts "#{Color::CYAN}📝 Creando nueva entrada...#{Color::RESET}"
BitacorasDB::BitacoraDB.with_connection do |db| BitacorasDB::BitacoraDB.with_connection do |db|
@@ -84,13 +90,38 @@ module ADN
bitacora_id = bitacora['id'] bitacora_id = bitacora['id']
# Obtener modo desde jornada actual si no se especificó
if modo_resuelto.nil?
entradas = db.list_entradas(bitacora_id: bitacora_id, limit: 10)
jornada = entradas.find { |e| e['descripcion']&.downcase&.include?('inicio de jornada') }
if jornada && jornada['modo']
modo_resuelto = jornada['modo']
puts " #{Color::DIM} Modo resuelto desde jornada: #{modo_resuelto == 'P' ? 'Presencial' : 'Remoto'}#{Color::RESET}"
else
modo_resuelto = 'P' # default
puts " #{Color::DIM} Sin jornada activa, usando default: Presencial#{Color::RESET}"
end
end
# Calcular estado automáticamente desde hora_fin
estado_resuelto = opts[:estado]
if estado_resuelto.nil?
if opts[:fin]
estado_resuelto = '✅'
puts " #{Color::DIM} Estado calculado: ✅ (tiene hora de fin)#{Color::RESET}"
else
estado_resuelto = '⏳'
puts " #{Color::DIM} Estado calculado: ⏳ (sin hora de fin)#{Color::RESET}"
end
end
# Crear la entrada # Crear la entrada
entrada = db.create_entrada( entrada = db.create_entrada(
inicio: opts[:inicio], inicio: opts[:inicio],
descripcion: opts[:descripcion], descripcion: opts[:descripcion],
fin: opts[:fin], fin: opts[:fin],
estado: opts[:estado], estado: estado_resuelto,
modo: opts[:modo], modo: modo_resuelto,
es_ia: opts[:es_ia], es_ia: opts[:es_ia],
bitacora_id: bitacora_id, bitacora_id: bitacora_id,
nodo_id: nodo_id, nodo_id: nodo_id,
@@ -98,15 +129,9 @@ module ADN
) )
puts "#{Color::GREEN}✅ Entrada creada exitosamente#{Color::RESET}" puts "#{Color::GREEN}✅ Entrada creada exitosamente#{Color::RESET}"
puts ""
puts " #{Color::BOLD}ID:#{Color::RESET} #{entrada['id']}"
puts " #{Color::BOLD}Inicio:#{Color::RESET} #{entrada['inicio']}" puts " #{Color::BOLD}Inicio:#{Color::RESET} #{entrada['inicio']}"
puts " #{Color::BOLD}Fin:#{Color::RESET} #{entrada['fin'] || '(sin fin)'}" puts " #{Color::BOLD}Fin:#{Color::RESET} #{entrada['fin'] || '(sin fin)'}"
puts " #{Color::BOLD}Descripción:#{Color::RESET} #{entrada['descripcion']}" puts " 📝 #{Color::BOLD}Descripción:#{Color::RESET} #{entrada['descripcion']}"
puts " #{Color::BOLD}Estado:#{Color::RESET} #{entrada['estado']}"
puts " #{Color::BOLD}Modo:#{Color::RESET} #{entrada['modo'] == 'P' ? 'Presencial' : 'Remoto'}"
puts " #{Color::BOLD}IA:#{Color::RESET} #{entrada['es_ia'] ? 'Sí' : 'No'}"
puts " #{Color::BOLD}Bitácora:#{Color::RESET} #{fecha_hoy} (ID: #{bitacora_id})"
mostrar_pendientes(db) mostrar_pendientes(db)
end end
@@ -129,6 +154,7 @@ module ADN
opt.on("--fin HH:MM", "Nueva hora de fin") { |f| opts[:fin] = f } opt.on("--fin HH:MM", "Nueva hora de fin") { |f| opts[:fin] = f }
opt.on("--descripcion TEXTO", "Nueva descripción") { |d| opts[:descripcion] = d } opt.on("--descripcion TEXTO", "Nueva descripción") { |d| opts[:descripcion] = d }
opt.on("--estado ESTADO", "Nuevo estado (⏳, ✅, ❌, ⚠️, ⏸️)") { |e| opts[:estado] = e } opt.on("--estado ESTADO", "Nuevo estado (⏳, ✅, ❌, ⚠️, ⏸️)") { |e| opts[:estado] = e }
opt.on("--modo MODO", "Modo (P=Presencial, R=Remoto)") { |m| opts[:modo] = m }
opt.on("--nodo NOMBRE", "Nuevo nodo") { |n| opts[:nodo_raw] = n } opt.on("--nodo NOMBRE", "Nuevo nodo") { |n| opts[:nodo_raw] = n }
opt.on("-h", "--help", "Mostrar ayuda") do opt.on("-h", "--help", "Mostrar ayuda") do
puts opt puts opt
@@ -144,13 +170,21 @@ module ADN
end end
if opts.empty? if opts.empty?
puts "#{Color::YELLOW}⚠ No se especificó nada para actualizar. Use --fin, --inicio, --descripcion, --estado o --nodo#{Color::RESET}" puts "#{Color::YELLOW}⚠ No se especificó nada para actualizar. Use --fin, --inicio, --descripcion, --estado, --modo o --nodo#{Color::RESET}"
return return
end end
puts "#{Color::CYAN}🔄 Actualizando evento #{id_evento}...#{Color::RESET}" puts "#{Color::CYAN}🔄 Actualizando evento #{id_evento}...#{Color::RESET}"
BitacorasDB::BitacoraDB.with_connection do |db| BitacorasDB::BitacoraDB.with_connection do |db|
# Calcular estado automáticamente si se proporciona --fin (sin verificar entrada actual)
if opts.key?(:fin) && !opts.key?(:estado)
if opts[:fin] && !opts[:fin].empty?
opts[:estado] = '✅'
puts " #{Color::DIM} Estado calculado automáticamente: ✅ (hora de fin agregada)#{Color::RESET}"
end
end
if opts.key?(:nodo_raw) if opts.key?(:nodo_raw)
if opts[:nodo_raw].nil? || opts[:nodo_raw].empty? if opts[:nodo_raw].nil? || opts[:nodo_raw].empty?
opts[:nodo_id] = nil opts[:nodo_id] = nil
@@ -171,6 +205,7 @@ module ADN
puts "#{Color::GREEN}✅ Evento #{id_evento} actualizado exitosamente.#{Color::RESET}" puts "#{Color::GREEN}✅ Evento #{id_evento} actualizado exitosamente.#{Color::RESET}"
puts " #{Color::BOLD}Inicio:#{Color::RESET} #{res['inicio']}" puts " #{Color::BOLD}Inicio:#{Color::RESET} #{res['inicio']}"
puts " #{Color::BOLD}Fin:#{Color::RESET} #{res['fin'] || '(sin fin)'}" puts " #{Color::BOLD}Fin:#{Color::RESET} #{res['fin'] || '(sin fin)'}"
puts " 📝 #{Color::BOLD}Descripción:#{Color::RESET} #{res['descripcion']}"
else else
puts "#{Color::YELLOW}⚠ No se pudo actualizar el evento. ¿Existe el ID #{id_evento}?#{Color::RESET}" puts "#{Color::YELLOW}⚠ No se pudo actualizar el evento. ¿Existe el ID #{id_evento}?#{Color::RESET}"
end end
@@ -184,7 +219,7 @@ module ADN
# Comando: evento:listar [OPCIONES] - Listar entradas con filtros # Comando: evento:listar [OPCIONES] - Listar entradas con filtros
def comando_evento_listar(args) def comando_evento_listar(args)
opts = { limit: 20, offset: 0, nodo: nil, estado: nil, buscar: nil, desde: nil, hasta: nil } opts = { limit: 20, offset: 0, nodo: nil, estado: nil, buscar: nil, desde: nil, hasta: nil, detalle: false }
parser = OptionParser.new do |opt| parser = OptionParser.new do |opt|
opt.banner = "Uso: adn db evento:listar [OPCIONES]" opt.banner = "Uso: adn db evento:listar [OPCIONES]"
@@ -209,6 +244,9 @@ module ADN
opt.on("--hasta FECHA", "Filtrar hasta fecha (YYYY-MM-DD)") do |h| opt.on("--hasta FECHA", "Filtrar hasta fecha (YYYY-MM-DD)") do |h|
opts[:hasta] = h opts[:hasta] = h
end end
opt.on("--detalle", "Mostrar descripciones completas (formato vertical)") do
opts[:detalle] = true
end
opt.on("-h", "--help", "Mostrar ayuda") do opt.on("-h", "--help", "Mostrar ayuda") do
puts opt puts opt
exit exit
@@ -253,21 +291,38 @@ module ADN
return return
end end
puts "" if opts[:detalle]
puts "#{Color::BOLD}#{"ID".ljust(5)} #{"Inicio".ljust(8)} #{"Fin".ljust(8)} #{"Nodo".ljust(15)} #{"Estado".ljust(3)} #{"Descripción".ljust(40)}#{Color::RESET}" # Formato vertical con descripciones completas
puts "#{"" * 5} #{"" * 8} #{"" * 8} #{"" * 15} #{"" * 3} #{"" * 40}" entradas.each_with_index do |e, i|
puts "#{Color::DIM}#{"" * 60}#{Color::RESET}" if i > 0
id = e['id'].to_s
inicio = e['inicio'][0..7]
fin = e['fin'] ? e['fin'][0..7] : '--:--'
nodo = e['nodo_nombre'] || '(sin nodo)'
estado = e['estado']
desc = e['descripcion']
entradas.each do |e| puts "#{estado} #{Color::BOLD}##{id}#{Color::RESET} | #{inicio}#{fin} | #{Color::CYAN}#{nodo}#{Color::RESET}"
id = e['id'].to_s puts " #{desc}"
inicio = e['inicio'][0..7] # HH:MM:SS -> HH:MM end
fin = e['fin'] ? e['fin'][0..7] : '--:--' else
nodo = e['nodo_nombre'] || '(sin nodo)' # Formato tabla compacta (original)
nodo = nodo[0..13] + '...' if nodo.length > 15 puts ""
estado = e['estado'] puts "#{Color::BOLD}#{"ID".ljust(5)} #{"Inicio".ljust(8)} #{"Fin".ljust(8)} #{"Nodo".ljust(15)} #{"Estado".ljust(3)} #{"Descripción".ljust(40)}#{Color::RESET}"
desc = e['descripcion'] puts "#{"" * 5} #{"" * 8} #{"" * 8} #{"" * 15} #{"" * 3} #{"" * 40}"
desc = desc[0..37] + '...' if desc.length > 40
puts "#{id.ljust(5)} #{inicio.ljust(8)} #{fin.ljust(8)} #{nodo.ljust(15)} #{estado.ljust(3)} #{desc.ljust(40)}" entradas.each do |e|
id = e['id'].to_s
inicio = e['inicio'][0..7] # HH:MM:SS -> HH:MM
fin = e['fin'] ? e['fin'][0..7] : '--:--'
nodo = e['nodo_nombre'] || '(sin nodo)'
nodo = nodo[0..13] + '...' if nodo.length > 15
estado = e['estado']
desc = e['descripcion']
desc = desc[0..37] + '...' if desc.length > 40
puts "#{id.ljust(5)} #{inicio.ljust(8)} #{fin.ljust(8)} #{nodo.ljust(15)} #{estado.ljust(3)} #{desc.ljust(40)}"
end
end end
puts "" puts ""
+1 -1
View File
@@ -1 +1 @@
1773604966 1773667642
+18
View File
@@ -0,0 +1,18 @@
# Script para configurar proxy SOCKS5 via SSH en dc-dasuten
# Ejecutar en dc-dasuten via PowerShell/CMD
# Configurar el proxy del sistema para usar el tunnel SSH
$proxyServer = "127.0.0.1:1080"
# Configurar proxy WinHTTP
netsh winhttp set proxy $proxyServer
# Configurar proxy para Internet Explorer / sistema
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name ProxyEnable -Value 1
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name ProxyServer -Value $proxyServer
# Para PowerShell (si es necesario)
[System.Net.WebRequest]::DefaultWebProxy = [System.Net.WebRequest]::GetSystemWebProxy()
Write-Host "Proxy configurado: $proxyServer"
Write-Host "Ahora el tráfico de Windows irá a través del tunnel SSH"
+22
View File
@@ -0,0 +1,22 @@
#!/bin/bash
# Script para configurar sudo sin contraseña en srv-dasu
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CANDADOS="$SCRIPT_DIR/../../adn/tools/seguridad/candados.rb"
# Cargar credenciales root
eval "$($CANDADOS load srv-dasu:root)"
# Verificar conexión y configurar sudo
sshpass -p "$SRV_DASU_ROOT_PASS" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 rmonla@$1 "
echo 'rmonla ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/rmonla > /dev/null
sudo chmod 440 /etc/sudoers.d/rmonla
sudo -n whoami
"
if [ $? -eq 0 ]; then
echo "✓ sudo sin contraseña configurado exitosamente"
else
echo "✗ Error al configurar sudo"
exit 1
fi
+32
View File
@@ -0,0 +1,32 @@
#!/bin/bash
# Script para iniciar tunnel SOCKS5 SSH en dc-dasuten
# Ejecutar via Task Scheduler o manualmente
SERVICE="ssh"
TUNNEL_HOST="100.112.46.104"
TUNNEL_USER="rmonla"
TUNNEL_PORT="1080"
# Buscar Plink (PuTTY) o usar SSH nativo
if [ -f "/c/Windows/System32/plink.exe" ]; then
SSH_CMD="/c/Windows/System32/plink.exe"
else
SSH_CMD="ssh"
fi
# Iniciar tunnel SSH en background
echo "Iniciando tunnel SOCKS5 a $TUNNEL_HOST..."
$SSH_CMD -D $TUNNEL_PORT -N -f -C $TUNNEL_USER@$TUNNEL_HOST
if [ $? -eq 0 ]; then
echo "Tunnel SOCKS5 iniciado en puerto $TUNNEL_PORT"
# Configurar proxy del sistema
echo "Configurando proxy del sistema..."
netsh winhttp set proxy 127.0.0.1:$TUNNEL_PORT
echo "Proxy configurado. Ahora puede descargar Tailscale."
else
echo "Error al iniciar tunnel SSH"
exit 1
fi
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
# Script para instalar Tailscale en dc-dasuten via SMB
echo "===Instalando Tailscale en dc-dasuten==="
# Cargar credenciales
eval $(ruby adn/tools/seguridad/candados.rb load admindasu)
# Copiar instalador a dc-dasuten via SMB
echo "Copiando instalador..."
smbclient -U "DASUTEN\\admindasu%$ADMINDASU_PASS" //10.0.100.10/c\$ -c "put /tmp/tailscale-setup.exe tailscale-setup.exe; exit"
echo "Instalando Tailscale..."
# Ejecutar instalador remotamente via psexec o similar
echo "Para completar, ejecutar manualmente en dc-dasuten:"
echo " C:\\tailscale-setup.exe /S"
echo " Start-Process tailscale.exe -ArgumentList up"
@@ -0,0 +1,23 @@
#!/bin/bash
# Script para copiar e instalar Tailscale en VMs Windows
# Cargar credenciales desde candados
eval $(ruby /home/rmonla/Documentos/GitHub/dtic-DIIAA/adn/tools/seguridad/candados.rb load admindasu)
TARGET_VM=$1
if [ -z "$TARGET_VM" ]; then
echo "Uso: $0 <vm-ip>"
exit 1
fi
echo "Copiando Tailscale a $TARGET_VM..."
sshpass -p "$ADMINDASU_PASS" scp -o StrictHostKeyChecking=no -P 7022 /tmp/tailscale-setup.exe "admindasu@${TARGET_VM}:/tmp/"
echo "Instalando Tailscale en $TARGET_VM..."
sshpass -p "$ADMINDASU_PASS" ssh -o StrictHostKeyChecking=no -p 7022 "admindasu@${TARGET_VM}" "powershell -Command \"Start-Process -FilePath 'C:\\tmp\\tailscale-setup.exe' -ArgumentList '/S' -Wait\""
echo "Configurando Tailscale en $TARGET_VM..."
sshpass -p "$ADMINDASU_PASS" ssh -o StrictHostKeyChecking=no -p 7022 "admindasu@${TARGET_VM}" "powershell -Command \"& 'C:\\Program Files\\Tailscale\\tailscale.exe' up --authkey $TAILSCALE_DASUTEN_AUTHKEY\""
echo "Verificando estado..."
sshpass -p "$ADMINDASU_PASS" ssh -o StrictHostKeyChecking=no -p 7022 "admindasu@${TARGET_VM}" "powershell -Command \"& 'C:\\Program Files\\Tailscale\\tailscale.exe' status\""
+30
View File
@@ -0,0 +1,30 @@
# Bitácora 2026-03-16
---
## 📋 Control de Gestión
### Pendientes
| ID | Nodo | Detalle |
| :--- | :--- | :--- |
### En Proceso
| ID | Nodo | Detalle |
| :--- | :--- | :--- |
### Resumen de Actividades
| Nodo | Resumen Integral |
| :--- | :--- |
---
## 📝 Actividades Detalladas
<!-- Agregar actividades por nodo aquí -->
---
<!-- 🤖 PREMISAS DE TRABAJO (IA): Fuente de Verdad → adn/05_ia.md -->
-15
View File
@@ -1,15 +0,0 @@
Vamos a seguir agregando mejoras al ecosistema ADN a gregando nuevas herramientas y mejorando las existentes segun el plan docs/proy/p2604_mejoras_ADN/P2604_mejoras_ADN.md.
Puedes buscar como mejorar y sanear las herramientas existentes.
Continúa el trabajo priorizando siempre el uso y la optimización de las herramientas definidas en el ecosistema ADN, con el objetivo de mejorarlas y hacerlas reutilizables en el futuro. Si es necesario crear nuevas herramientas, asegúrate de que sigan los mismos principios de sostenibilidad y evita soluciones temporales o de un solo uso.
Para más contexto, consulta los lineamientos en `adn/README.md`, así como el índice actualizado de herramientas disponibles en ADN.
Recuerda seguir el flujo de trabajo establecido:
1. Actualizar el plan.
2. Documentar el progreso en la bitácora web.
3. Ejecutar las tareas correspondientes.
**Menos es mas, mejora continua y armonía integral**
+18
View File
@@ -0,0 +1,18 @@
PROMPT
En el plan docs/proy/p2601_dasuten/plan/P2601_6.1.B_AD-Join:_pc-dasu0_al_Dominio.md hay que agregar items y subitems de cambios de nombres de host de los nodos sql-dasuten a dasu-srvv-sql, dc-dasuten a dasu-srvv-dc y pcv-dasu0 a dasu-pcv0 que se deben realizar.
Continúa el trabajo priorizando siempre el uso y la optimización de las herramientas definidas en el ecosistema ADN, con el objetivo de mejorarlas y hacerlas reutilizables en el futuro. Si es necesario crear nuevas herramientas, asegúrate de que sigan los mismos principios de sostenibilidad y evita soluciones temporales o de un solo uso.
Para más contexto, consulta los lineamientos en `adn/README.md`, así como el índice actualizado de herramientas disponibles en ADN.
Recuerda que, si realizas optimizaciones o mejoras, el ecosistema ADN debe mantenerse actualizado para reflejar dichos cambios.
Sigue el flujo de trabajo establecido:
1. **Bitácora First:** registrar primero el contexto o situación en la bitácora.
2. **Actualizar el plan.**
3. **Ejecutar las tareas correspondientes.**
4. **Actualizar nuevamente la bitácora** con los resultados y avances.
**Menos es más, mejora continua y armonía integral.**
+203
View File
@@ -0,0 +1,203 @@
# RFC-ADN-01
## Convención de Identificación y Documentación de Proyectos
### Estado
Propuesta
### Alcance
Esta convención define el **esquema de identificación, estructura y documentación de proyectos** dentro del repositorio, principalmente en:
```
docs/proy
```
Su objetivo es garantizar:
* consistencia
* trazabilidad
* fácil navegación
* reutilización del conocimiento
* automatización futura
---
# 1. Identificación de proyectos
Cada proyecto debe tener un **identificador único**.
### Formato
```
PYYNN_TEMA
```
Donde:
| Elemento | Significado |
| -------- | ------------------------ |
| P | Prefijo de proyecto |
| YY | Año de creación |
| NN | Número correlativo |
| TEMA | Nombre corto descriptivo |
### Ejemplo
```
P2601_Dasuten
```
Interpretación:
* Proyecto 01
* Año 2026
* Tema: Dasuten
---
# 2. Estructura de secciones
Cada proyecto puede dividirse en **secciones y subsecciones**.
### Formato
```
PYYNN.NN.NN.TEMA
```
| Elemento | Significado |
| -------- | -------------------------- |
| PYYNN | Identificador del proyecto |
| NN | Sección |
| NN | Subsección |
| TEMA | Nombre corto |
### Ejemplo
```
P2601.01.01.Red-SrvDasu
```
Interpretación:
* Proyecto: P2601
* Sección: 01
* Subsección: 01
* Tema: Red del servidor Dasu
---
# 3. Datos de cabecera del proyecto
Cada proyecto debe iniciar con un bloque de metadatos.
Ejemplo:
```
Proyecto: P2601_Dasuten
Estado: En desarrollo
Versión: v0.1
Responsable: TIC
Fecha inicio: 2026
Ámbito: Infraestructura / Sistemas
```
Campos recomendados:
* Proyecto
* Estado
* Versión
* Fecha inicio
* Responsable
* Ámbito
* Contexto
* Objetivo
---
# 4. Estructura sugerida de documentación
Dentro de cada proyecto:
```
docs/proy/
P2601_Dasuten/
├── README.md
├── bitacora.md
├── plan.md
├── 01_contexto.md
├── 02_arquitectura.md
├── 03_implementacion.md
├── 04_operacion.md
├── 05_mejoras.md
```
---
# 5. Principios de diseño
La documentación debe seguir estos principios:
### Simplicidad
Evitar estructuras complejas.
### Escalabilidad
Debe funcionar tanto para proyectos pequeños como grandes.
### Navegabilidad
La estructura debe ser fácilmente entendible.
### Automatización futura
La nomenclatura debe permitir:
* generación automática de índices
* scripts de documentación
* trazabilidad entre proyectos
---
# 6. Integración con ecosistema ADN
Este estándar debe integrarse con el ecosistema ADN.
En particular:
* herramientas de documentación
* generación de plantillas
* bitácoras de proyectos
* automatización de repositorios
Referencia principal:
```
adn/README.md
```
---
# 7. Mejora continua
Este estándar **no es definitivo**.
Debe evolucionar mediante:
* nuevas necesidades
* retroalimentación del uso real
* optimización de herramientas ADN
---
# Principio rector
**Menos es más.
Mejora continua.
Armonía integral.**
@@ -3,7 +3,7 @@
**Fecha:** 11 de marzo de 2026 **Fecha:** 11 de marzo de 2026
**Autor:** Sistema ADN **Autor:** Sistema ADN
**Versión:** 1.0 **Versión:** 1.0
**Ubicación:** `docs/proy/p2601_dasuten/plan/P2601_6.1.A - Red_SrvDasu.md` **Ubicación:** `docs/proy/P2601_Dasuten/plan/P2601.06.01_Red-SrvDasu.md`
**Estado:** ✅ COMPLETADO **Estado:** ✅ COMPLETADO
## 📋 Resumen Ejecutivo ## 📋 Resumen Ejecutivo
@@ -0,0 +1,259 @@
# Plan: Unión de pc-dasu0 al Dominio DASUTeN (P2601 Fase 6.1.B)
**Fecha:** 11 de marzo de 2026 (Actualizado: 16/03/2026)
**Autor:** Sistema ADN
**Versión:** 4.1
**Estado:** ⏳ EN EJECUCIÓN (Fase 1 - Normalización de Nombres)
**Proyecto:** [P2601 DASUTEN](../P2601_dasuten.md)
## 📋 Resumen Ejecutivo
Unir la PC física `pc-dasu0` (oficina DASUTeN) al dominio `dasuten.utnlr`. La infraestructura de soporte (DC, SQL, red) ya está operativa y validada con la VM de pruebas.
> **Fase 0 en curso:** Normalización de nombres de nodos para convención unificada.
**Nodos involucrados:**
| Nodo | Nuevo Nombre | Tipo | IP Interna | Tailscale | SSH 7022 | Estado |
|:-----|:-------------|:-----|:----------:|:---------:|:--------:|:------:|
| `dasu-srvv-dc` | (antes dc-dasuten) | VM 100 (DC/DNS) | `10.0.100.10` | ✅ | ⏳ pendiente | ⏳ Por renombrar |
| `dasu-srvv-sql` | (antes sql-dasuten) | VM 101 (SQL) | `10.0.100.11` | ✅ | ✅ | ⏳ Por renombrar |
| `dasu-pcv0` | (antes pcv-dasu0) | VM 102 (Test) | `10.0.100.12` | ❌ | ✅ | ⏳ Por renombrar |
| `dasu-pc0` | (antes pc-dasu0) | PC Física | `192.168.1.13` (DHCP) | ❌ offline | ✅ | ⏳ Por renombrar |
| `srv-dasu` | — | Hypervisor | `10.0.100.1` | ✅ (`100.112.46.104`) | ✅ | ✅ Operativo |
## 🔧 Topología de Red
```
[Internet] ← Router ISP → [srv-dasu (192.168.1.27)] ↔ [pc-dasu0 (192.168.1.13)]
│ │
│ NAT (10.0.100.1) │ Misma LAN física
▼ │
┌──────────────┐ │
│ 10.0.100.x │ │
│ dc-dasuten │ Ruta DNS: │
│ (.10) [AD] │ ← ← ← ← ← ← ← ← ┘
│ sql-dasuten │
│ (.11) [SQL] │
│ pcv-dasu0 │
│ (.12) [Test]│
└──────────────┘
```
**Conectividad de pc-dasu0 al dominio:**
- `pc-dasu0` y `srv-dasu` comparten router ISP → comunicación directa LAN (<2ms)
- `srv-dasu` actúa como subnet router Tailscale exponiendo `10.0.100.0/24`
- DNS del dominio (`10.0.100.10`) accesible via `srv-dasu` como gateway
## 🔒 Red Tailscale Unificada
**Cuenta:** `pcdasu0@frlr.utn.edu.ar` | **Gestión:** `./adn/tools/run tailscale`
| Nodo | Estado Tailscale | IP Tailscale |
|:-----|:----------------:|:------------:|
| `srv-ns8` | ✅ Activo (switch dual) | — |
| `srv-dasu` | ✅ Activo (subnet router) | `100.112.46.104` |
| `dc-dasuten` | ✅ Instalado | — |
| `sql-dasuten` | ✅ Instalado | — |
| `pc-dasu0` | ❌ Offline | `100.65.62.44` (anterior) |
## 📅 Fases de Implementación
### ✅ **FASE 1: Infraestructura y Conectividad** (EN CURSO)
> Toda la infraestructura de soporte está operativa. Incluyendo normalización de nombres.
#### 1.0 Normalización de Nombres
> Renombrar nodos para seguir convención unificada: `dasu-srvv-{rol}` y `dasu-pcv{n}` / `dasu-pc{n}`
| ID | Nodo Actual | Nuevo Nombre | Estado |
| :--- | :--- | :--- | :--- |
| 1.0.1 | `sql-dasuten` (VM 101) | `dasu-srvv-sql` | ⏳ Pendiente |
| 1.0.2 | `dc-dasuten` (VM 100) | `dasu-srvv-dc` | ⏳ Pendiente |
| 1.0.3 | `pcv-dasu0` (VM 102) | `dasu-pcv0` | ⏳ Pendiente |
| 1.0.4 | `pc-dasu0` (PC Física) | `dasu-pc0` | ⏳ Pendiente |
**Pasos para cada nodo (VM):**
1. Apagar VM
2. Cambiar hostname en SO Windows
3. Renombrar en Proxmox (display name + name)
4. Actualizar ficha en `nodos/`
5. Actualizar registros DNS en AD
6. Actualizar inventario ADN (`./adn/tools/run db nodo:actualizar`)
7. Encender y verificar conectividad
**Pasos para PC física (pc-dasu0):**
1. Cambiar nombre de equipo en Windows
2. Actualizar ficha en `nodos/`
3. Actualizar DNS en AD post-unión al dominio
4. Actualizar inventario ADN
#### 1.1-1.13 Tareas de Infraestructura
- [x] **1.1** Diagnóstico de topología de red (IPs locales, subredes, latencia)
- [x] **1.2** Validar DNS: `10.0.100.10` resuelve `dc-dasuten.dasuten.utnlr`
- [x] **1.3** Conectividad directa LAN entre `pc-dasu0``srv-dasu` (<2ms) ✅
- [x] **1.4** Instalar SSH 7022 en `pc-dasu0` via w-zombi ✅
- [x] **1.5** Migrar `srv-dasu` a red Tailscale `pcdasu0@frlr.utn.edu.ar`
- [x] **1.6** Configurar NAT en `srv-dasu` → VMs con acceso internet ✅
- [x] **1.7** Backups VZDump de dc-dasuten y sql-dasuten ✅
- [x] **1.8** Instalar Tailscale en dc-dasuten y sql-dasuten ✅
- [x] **1.9** Obtener acceso sudo a `srv-dasu`
- [x] **1.10** Verificar credenciales de dominio (`admindasu` en bóveda `candados`) ✅
- [x] **1.11** Documentar problemas de conectividad intermitente ✅
- [x] **1.12** Verificar SSH 7022 funcional en dc-dasuten (⏳ pendiente verificar → ⚠️ filtrado/red)
- [ ] **1.13** Reactivar Tailscale en `pc-dasu0`
### 🛠 **FASE 2: Preparación de pc-dasu0** (PRÓXIMA)
**Hito:** Configuración base lista para unión al dominio.
**Herramientas ADN:** `ssh <nodo> <cmd>`, `nodos info <nodo>`, `contexto <nodo>`
- [ ] **2.1** Verificar requisitos: Windows 10 (versión, updates, .NET Framework)
```powershell
# Via SSH o RustDesk
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
```
- [ ] **2.2** Configurar red de `pc-dasu0`:
- **DNS Primario:** `10.0.100.10` (dc-dasuten, via ruta a srv-dasu)
- **DNS Secundario:** `8.8.8.8`
- **Suffix DNS:** `dasuten.utnlr`
- **Gateway:** Router ISP local (default)
- [ ] **2.3** Agregar ruta estática a `10.0.100.0/24` via `srv-dasu` (192.168.1.27)
```powershell
route add 10.0.100.0 MASK 255.255.255.0 192.168.1.27 -p
```
- [ ] **2.4** Validar conectividad a puertos de dominio:
```powershell
Test-NetConnection -ComputerName 10.0.100.10 -Port 389 # LDAP
Test-NetConnection -ComputerName 10.0.100.10 -Port 636 # LDAPS
Test-NetConnection -ComputerName 10.0.100.10 -Port 3268 # Global Catalog
Test-NetConnection -ComputerName 10.0.100.10 -Port 445 # SMB
```
- [ ] **2.5** Verificar resolución de nombres: `nslookup dc-dasuten.dasuten.utnlr`
- [ ] **2.6** Configurar firewall local (permitir puertos AD en subred `10.0.100.0/24`)
- [ ] **2.7** Crear backup de sistema y perfiles (Andrea/Romina)
- [ ] **2.8** Reactivar Tailscale con cuenta `pcdasu0@frlr.utn.edu.ar`
### 🔗 **FASE 3: Unión al Dominio**
**Hito:** `pc-dasu0` unida exitosamente a `dasuten.utnlr`.
- [ ] **3.1** Ejecutar unión al dominio:
```powershell
Add-Computer -DomainName "dasuten.utnlr" -Credential DASUTEN\admindasu -Restart
```
- [ ] **3.2** Verificar nombre en dominio: `pc-dasu0.dasuten.utnlr`
- [ ] **3.3** Reiniciar y validar login con cuenta de dominio
- [ ] **3.4** Verificar membresía en grupos AD
- [ ] **3.5** Aplicar GPOs básicas del dominio
### 👥 **FASE 4: Migración de Perfiles y Cierre**
**Hito:** Sistema en producción estable.
- [ ] **4.1** Migrar perfiles locales (Andrea/Romina) a cuentas de dominio
- [ ] **4.2** Configurar mapeo de unidades de red
- [ ] **4.3** Verificar acceso al sistema DASUTEN desde dominio
- [ ] **4.4** Monitorear estabilidad 48hs (conectividad, autenticación, GPO)
- [ ] **4.5** Actualizar ficha `nodos/pc-dasu0.md` con estado final
- [ ] **4.6** Registrar hitos en DB: `./adn/tools/run db hito:crear`
## 🚨 Procedimientos de Rollback
| Escenario | Acción |
|:----------|:-------|
| Fallo en unión | Desunir con credenciales locales, restaurar DNS original |
| Conectividad rota | Activar Tailscale como ruta alternativa, diagnosticar LAN |
| Perfiles perdidos | Restaurar desde backup pre-unión (Fase 2.7) |
| DC inaccesible | Revertir a `pcv-dasu0` (VM) para operaciones críticas |
## 🔧 Notas Técnicas
### Puertos Críticos (AD DS)
| Puerto | Protocolo | Servicio |
|:-------|:----------|:---------|
| 389/636 | TCP | LDAP/LDAPS |
| 3268/3269 | TCP | Global Catalog |
| 445 | TCP | SMB |
| 135, 137-139 | TCP/UDP | NetBIOS/RPC |
| 123 | UDP | NTP |
| 88 | TCP/UDP | Kerberos |
### Dependencias
1. **Router ISP:** Comunicación LAN entre `pc-dasu0` ↔ `srv-dasu`
2. **NAT srv-dasu:** Ruta `pc-dasu0` → `10.0.100.0/24` via `192.168.1.27`
3. **dc-dasuten operativo:** DNS + AD DS funcional
4. **Credenciales:** `DASUTEN\admindasu` (bóveda: `candados`, clave: `admindasu`)
5. **Sincronización NTP:** Entre todos los nodos del dominio
### Herramientas ADN Disponibles
```bash
# Diagnóstico y contexto
./adn/tools/run nodos info pc-dasu0
./adn/tools/run contexto dc-dasuten
./adn/tools/run ssh srv-dasu "ping -c3 10.0.100.10"
# Registro de progreso (DB-First)
./adn/tools/run db evento:crear --nodo pc-dasu0 --titulo "Título" --inicio HH:MM
./adn/tools/run db evento:listar --desde FECHA --detalle
# Verificación
./adn/tools/run salud --dashboard
```
## 📊 Métricas de Éxito
| Métrica | Objetivo |
|:--------|:---------|
| Conectividad LAN | >99% uptime `pc-dasu0` ↔ `srv-dasu` |
| Conectividad dominio | >95% uptime `pc-dasu0` → `dc-dasuten` |
| Login dominio | <15 segundos |
| Latencia LAN | <5ms |
| Estabilidad post-unión | 0 incidentes críticos en 72hs |
| Perfiles migrados | Sin pérdida de datos |
## 📚 Referencias
1. [Proyecto P2601 DASUTEN](../P2601_dasuten.md)
2. [Nodo: pc-dasu0](../../../nodos/pc-dasu0.md)
3. [Nodo: pcv-dasu0](../../../nodos/pcv-dasu0.md) *(VM referencia, ya unida al dominio)*
4. [Nodo: dc-dasuten](../../../nodos/dc-dasuten.md)
5. [Nodo: srv-dasu](../../../nodos/srv-dasu.md)
6. [Plan 06.01: Red srv-dasu](P2601.06.01_Red-SrvDasu.md)
---
## 📋 Historial de Sesiones
### 16/03/2026 — Sesión de Seguimiento (Mañana)
- ✅ Inicio de jornada remota 10:00-10:01 (#1104)
- ✅ Verificación SSH dc-dasuten: puertos SSH no accesibles desde srv-dasu (probable filtro Windows Firewall)
- ⏳ Tarea 1.13: Reactivar Tailscale en pc-dasu0 (próxima)
### 15-16/03/2026 — Sesión de Infraestructura (Madrugada)
- ✅ Backups VZDump de dc-dasuten (#1093) y sql-dasuten (#1094)
- ✅ Tailscale instalado en dc-dasuten (#1096) y sql-dasuten (#1097)
- ❌ VM proxy fallida (#1091) → Revertida (#1090, #1092)
- ✅ Acceso sudo a srv-dasu configurado (#1089)
- ⏳ SSH 7022 en dc-dasuten pendiente verificar (#1098)
### 15/03/2026 — Sesión Principal
- ✅ Herramienta SSH CLI creada (P2604-S11) y refactorizada (S12-S14)
- ✅ Diagnóstico remoto via SSH ADN (#1076)
- ✅ DNS validado: `10.0.100.10` resuelve dominio (#1083)
- ✅ NAT configurado, VMs con internet (#1081)
- ✅ README ADN actualizado con estructura real (#1080)
### 15/03/2026 — Análisis Inicial
- ✅ Análisis de plan AD-Join (#1082)
- ✅ Documentar problemas conectividad (#1086)
- ✅ Decisión: mantener subnet router + Tailscale directo en VMs (#1084-#1085)
### 11/03/2026 — Creación del Plan (v1.0)
- Creación inicial del plan con topología de red identificada.
- Identificación de comunicación directa LAN como estrategia primaria.
@@ -161,6 +161,42 @@ Mejoras atómicas, incrementales y reutilizables. Una herramienta por vez.
--- ---
## Extensión P2604: Bitácora Web + Mejoras Eventos (Marzo 2026)
> **Objetivo**: Mejorar la experiencia de usuario en la bitácora web y la consistencia en el CLI de eventos.
### Fase 11: Bitácora Web (Mejora Continua)
| ID | Mejora | Herramienta | Estado |
| :--- | :--- | :--- | :--- |
| B1 | Auto-refresh cada 30 segundos | React App.tsx | ✅ |
| B2 | Refresh al recuperar foco (visibility change) | React App.tsx | ✅ |
| B3 | Smart refresh - solo actualizar si hay cambios (comparando max_id) | Backend + Frontend | ✅ |
| B4 | Documentar en README.md | `adn/README.md` | 📍 |
### Fase 12: Consistencia de Eventos (Menos es Más)
> El estado y modo deben ser valores derivados, no ingresados manualmente.
| ID | Mejora | Archivo | Estado |
| :--- | :--- | :--- | :--- |
| E1 | Estado calculado automáticamente desde `hora_fin` (si tiene → ✅, si no → ⏳) | `cli/db/evento.rb` | ✅ |
| E2 | Modo resuelto automáticamente desde la última jornada del día | `cli/db/evento.rb` | ✅ |
| E3 | Estado automático también al actualizar evento con `--fin` | `cli/db/evento.rb` | ✅ |
| E4 | Actualizar ayuda y documentación | `adn/README.md` | 📍 |
**Comportamiento:**
- Al crear evento sin especificar `--estado`:
- Si tiene `--fin` → estado = "✅" (completado)
- Si NO tiene `--fin` → estado = "⏳" (en proceso)
- Al crear evento sin especificar `--modo`:
- Busca la última entrada que contenga "inicio de jornada" y usa su modo
- Si no hay jornada → usa default "P" (Presencial)
- Al actualizar evento con `--fin` sin especificar `--estado`:
- Automatically set to "✅"
---
## Progreso ## Progreso
``` ```
@@ -174,6 +210,8 @@ Fase 7: ██████████ 100% (DOC1-DOC3: docs/tecnica/)
Fase 8: ██████████ 100% (CI1-CI2: GitHub Actions) Fase 8: ██████████ 100% (CI1-CI2: GitHub Actions)
Fase 9: ██████████ 100% (M1-M5: MSP CLI) Fase 9: ██████████ 100% (M1-M5: MSP CLI)
Fase 10: ██████████ 100% (S1-S15 done ✔) Fase 10: ██████████ 100% (S1-S15 done ✔)
Fase 11: ██████████ 100% (B1-B3 done)
Fase 12: ████████░░ 67% (E1-E3 done)
``` ```
--- ---
@@ -184,16 +222,16 @@ Fase 10: ██████████ 100% (S1-S15 done ✔)
| :--- | :--- | | :--- | :--- |
| Tests pasando | 15 | | Tests pasando | 15 |
| Archivos creados | 12 | | Archivos creados | 12 |
| Archivos modificados | 8 | | Archivos modificados | 10 |
| Archivos limpiados/movidos | 20+ | | Archivos limpiados/movidos | 20+ |
| Fases completadas | 9/10 (90%) | | Fases completadas | 11/12 (92%) |
| Documentos técnicos | Consolidados en `adn/README.md` | | Documentos técnicos | Consolidados en `adn/README.md` |
--- ---
## Próxima Acción ## Próxima Acción
**S10**: Migrar `SubcomandoSalud` al namespace `ADN::` y reescribir para consultar DB (DB-First) **B3 + E4**: Actualizar `adn/README.md` con las nuevas funcionalidades (auto-refresh, estado/modo calculado)
--- ---
@@ -201,5 +239,5 @@ Fase 10: ██████████ 100% (S1-S15 done ✔)
- Punto de verdad: [`adn/README.md`](../../adn/README.md) - Punto de verdad: [`adn/README.md`](../../adn/README.md)
- ADN IA: [`05_ia.md`](../../adn/05_ia.md) - ADN IA: [`05_ia.md`](../../adn/05_ia.md)
- Bitácoras: ID 1054-1056, 1073 - Bitácoras: ID 1054-1056, 1073, 1106, 1112
- Planes históricos movidos a: `docs/_hist/plan/` - Planes históricos movidos a: `docs/_hist/plan/`
@@ -1,321 +0,0 @@
# Plan: Unión de pc-dasu0 al Dominio DASUTeN (P2601 Fase 6.1.B)
**Fecha:** 11 de marzo de 2026
**Autor:** Sistema ADN
**Versión:** 2.0
**Ubicación:** `docs/proy/p2601_dasuten/plan/P2601_6.1.B - AD-Join: pc-dasu0 al Dominio.md`
**Estado:** ⏳ PLANIFICACIÓN
**Proyecto:** [P2601 DASUTEN](../../P2601_dasuten.md)
## 📋 Resumen Ejecutivo
Unir la PC física `pc-dasu0` (ubicada en la oficina DASUTeN) al dominio `dasuten.utnlr`, completando la Fase 6 del proyecto P2601. Este plan aborda los problemas de conectividad intermitente identificados en la red actual y establece un procedimiento validado basado en la experiencia exitosa con la VM de pruebas `pcv-dasu0`.
**Contexto Crítico:**
- `pc-dasu0` es la PC física (Ryzen 5, Windows 10) en la oficina DASUTeN
- `pcv-dasu0` (VM de pruebas) ya está unida exitosamente al dominio (validación previa)
- **INFORMACIÓN CRÍTICA:** `srv-dasu` y `pc-dasu0` comparten el mismo router ISP en la oficina DASUTeN
- Esta topología permite comunicación directa por capa 3 sin necesidad de Tailscale
- El dominio `dasuten.utnlr` opera en `dc-dasuten` (`10.0.100.10`)
- `srv-dasu` actúa como hypervisor con subred `10.0.100.0/24` y gateway `10.0.100.1`
## 🔧 Topología de Red Revisada
### Diagrama Conceptual
```
[Internet] ← Router ISP (Compartido) → [srv-dasu] ↔ [pc-dasu0]
│ │
└───────────────────────────────────────┘
Misma red local física
```
### Características Clave
1. **Router Compartido:** `srv-dasu` y `pc-dasu0` están detrás del mismo router del ISP
2. **Comunicación Directa Posible:** Conexión local por capa 3 sin intermediarios
3. **Simplificación de Conectividad:** Elimina dependencia exclusiva de Tailscale
4. **Latencia Reducida:** Comunicación local con latencia mínima (<1ms)
### Estrategias de Conectividad
#### Opción A: Comunicación Directa Local (PREFERIDA)
- **Ventajas:** Latencia mínima, sin dependencia externa, mayor estabilidad
- **Requisitos:** Configuración de red local adecuada, firewall permitido
- **Implementación:** IPs locales en misma subred, routing directo
#### Opción B: Tailscale como Backup
- **Ventajas:** Seguridad mejorada, tunelización cifrada, acceso remoto
- **Requisitos:** Tailscale funcionando en ambos nodos
- **Implementación:** Mantener como sistema de respaldo
#### Opción C: Híbrida (Directa + Tailscale)
- **Ventajas:** Resiliencia máxima, failover automático
- **Requisitos:** Configuración dual de red
- **Implementación:** Priorizar comunicación directa, fallback a Tailscale
#### 🔒 Red Tailscale Unificada (REQUERIMIENTO OBLIGATORIO)
Para asegurar la gestión y el monitoreo, todos los equipos del ecosistema deben coexistir en la misma red Tailscale:
- **Nodos:** `srv-ns8`, `srv-dasu`, `pc-dasu0`
- **Credenciales:** Gestionadas en la bóveda `candados` (clave: `tailscale_dasuten_user`)
- **Objetivo:** Garantizar visibilidad cruzada y túneles de administración remota persistentes.
- **Gestión ADN:** Implementado `./adn/tools/run tailscale switch <perfil>` para alternar entre cuentas.
- **Estado actual:**
- [x] `srv-ns8` (este equipo): Configurado con switch dual (dasuten/personal) ✅
- [x] `srv-dasu`: Migrado exitosamente a red `pcdasu0@frlr.utn.edu.ar` vía acceso local (IP: 100.112.46.104) ✅
- [ ] `pc-dasu0`: Offline en Tailscale, pendiente reactivar
## 🎯 Objetivos
1. **Primario:** Unir `pc-dasu0` al dominio `dasuten.utnlr` de forma estable y verificable
2. **Secundario:** Diagnosticar y resolver problemas de conectividad de red intermitente
3. **Validación:** Transferir configuración validada desde `pcv-dasu0` (VM de pruebas)
4. **Seguridad:** Establecer políticas de grupo y acceso seguro al sistema DASUTEN
5. **Topología:** Implementar comunicación directa local aprovechando router compartido
## 📅 Fases de Implementación
### 🔍 **FASE 1: Investigación de Topología de Red Actual**
**Hito 1.1:** Diagnóstico completo de conectividad entre `pc-dasu0` y la infraestructura DASUTEN
#### Semana 1: Análisis de Red y Topología
- [x] **1.1.1:** Verificar estado de Tailscale en `pc-dasu0` (IP actual: `100.100.145.51` - Estado: Offline)
- [x] **1.1.2:** Diagnosticar ruta de red desde `pc-dasu0` hacia `srv-dasu` (vía física/local a 192.168.1.27)
- [x] **1.1.3:** **CRÍTICO:** Probar conectividad directa local entre `pc-dasu0` y `srv-dasu`
- Identificar IPs locales asignadas por router ISP: `srv-dasu` (192.168.1.27) y `pc-dasu0` (192.168.1.13)
- Probar ping directo sin Tailscale (Éxito: < 2ms)
- Verificar acceso a puertos críticos localmente (RDP cerrado, firewall por defecto)
- [ ] **1.1.4:** Validar resolución DNS hacia `dc-dasuten.dasuten.utnlr` (`10.0.100.10`)
- [ ] **1.1.5:** Documentar problemas de conectividad intermitente y patrones identificados
- [x] **1.1.6:** **NUEVO:** Mapear topología de red local completa
- Identificar subred local del router ISP: `192.168.1.0/24`
- Documentar configuración DHCP del router: Asignando la `...13` y `...27`
- Verificar reglas de firewall locales
#### Semana 1: Preparación de Acceso
- [ ] **1.1.7:** Configurar acceso remoto seguro (RustDesk ID: `398 699 016`) -> Requiere acceso presencial o que RustDesk conecte para revisar Tailscale
- [x] **1.1.8:** Verificar credenciales de dominio en bóveda (`admindasu` guardada y operativa en candados)
- [ ] **1.1.9:** Establecer procedimiento de rollback (desunión de dominio)
- [ ] **1.1.10:** Preparar configuración de red dual (local + Tailscale)
- [x] **1.1.10a:** **CRÍTICO:** Migrar `srv-dasu` de red Tailscale `rmonla@gmail.com` a `pcdasu0@frlr.utn.edu.ar`
- [x] Ejecutar logout + login remoto (resuelto vía contingencia de puente manual desde la red local)
- [x] Autorizar URL de login manualmente
- [x] Verificar que `srv-dasu` resida en la nueva VPN (`100.112.46.104`)
- [x] **1.1.10b:** **CRÍTICO:** Instalar OpenSSH Server en `pc-dasu0` (puerto 7022)
- [x] Desplegar w-zombi en `srv-dasu` (192.168.1.27) como puente local
- [x] Activar payload `ssh_port7022.ps1` y `install_ssh_legacy.ps1` (instala SSH + configura puerto 7022 + firewall)
- [x] Ejecutar el agente zombi desde `pc-dasu0` via RustDesk
- [x] Verificar conectividad SSH a `pc-dasu0:7022` desde `srv-ns8` (Validado el estado Running via puente srv-dasu)
### 🛠 **FASE 2: Preparación de pc-dasu0**
**Hito 2.1:** Configuración base replicada desde `pcv-dasu0`
#### Semana 2: Configuración del Sistema y Red
- [ ] **2.1.1:** Verificar requisitos de Windows 10 (versión, updates, .NET Framework)
- [ ] **2.1.2:** **ACTUALIZADO:** Configurar adaptador de red con estrategia dual:
- **Configuración Local:** IP local según subred del router ISP
- **DNS Primario:** `10.0.100.10` (dc-dasuten) via comunicación directa
- **DNS Secundario:** `8.8.8.8` (fallback)
- **Gateway:** Router ISP local
- [ ] **2.1.3:** Aplicar configuración de red validada en `pcv-dasu0`
- [ ] **2.1.4:** Crear backup completo del sistema y perfiles de usuario actuales
- [ ] **2.1.5:** Preparar script de migración de perfiles locales a dominio
#### Semana 2: Validación Preliminar de Conectividad
- [ ] **2.1.6:** **ACTUALIZADO:** Probar conectividad a puertos críticos usando ambas rutas:
- **Ruta Local:** Comunicación directa sin Tailscale
- **Ruta Tailscale:** Via subnet router como backup
- **Puertos:** TCP 389, 636, 3268, 3269 (LDAP/GC)
- [ ] **2.1.7:** Verificar acceso a recursos compartidos del dominio
- [ ] **2.1.8:** Validar resolución de nombres NetBIOS (`DASUTEN`)
- [ ] **2.1.9:** **NUEVO:** Configurar reglas de firewall para comunicación local
- Permitir puertos de dominio en firewall local
- Configurar excepciones para subred local
### 🔗 **FASE 3: Unión al Dominio**
**Hito 3.1:** Unión exitosa de `pc-dasu0` a `dasuten.utnlr`
#### Semana 3: Procedimiento de Unión
- [ ] **3.1.1:** Ejecutar unión al dominio usando credenciales `DASUTEN\admindasu`
- [ ] **3.1.2:** Configurar nombre de equipo en dominio (`pc-dasu0.dasuten.utnlr`)
- [ ] **3.1.3:** Reiniciar y verificar autenticación en dominio
- [ ] **3.1.4:** Validar membresía en grupos de dominio apropiados
- [ ] **3.1.5:** Aplicar políticas de grupo (GPO) básicas del dominio
#### Semana 3: Migración de Perfiles y Configuración de Red Final
- [ ] **3.1.6:** Migrar perfiles de usuario local (Andrea/Romina) a cuentas de dominio
- [ ] **3.1.7:** Configurar mapeo de unidades de red y recursos compartidos
- [ ] **3.1.8:** Verificar acceso al sistema DASUTEN desde el dominio
- [ ] **3.1.9:** **NUEVO:** Optimizar configuración de red para comunicación directa
- Priorizar ruta local sobre Tailscale
- Configurar métricas de ruta apropiadas
- Establecer monitoreo de conectividad dual
### ✅ **FASE 4: Validación y Monitoreo**
**Hito 4.1:** Sistema operativo en producción estable
#### Semana 4: Pruebas Integrales
- [ ] **4.1.1:** Ejecutar suite de pruebas del sistema DASUTEN
- [ ] **4.1.2:** **ACTUALIZADO:** Validar conectividad persistente durante 24-48 horas usando:
- Comunicación directa local (métrica principal)
- Tailscale como respaldo (métrica secundaria)
- [ ] **4.1.3:** Monitorear logs de autenticación y eventos de dominio
- [ ] **4.1.4:** Verificar funcionamiento de aplicaciones críticas
#### Semana 4: Documentación y Cierre
- [ ] **4.1.5:** Actualizar documentación de `nodos/pc-dasu0.md` con nueva topología
- [ ] **4.1.6:** Registrar hitos en dashboard P2601
- [ ] **4.1.7:** Documentar lecciones aprendidas y procedimientos
- [ ] **4.1.8:** **NUEVO:** Establecer monitoreo continuo de conectividad dual
- Alertas por fallo de comunicación directa
- Métricas de performance de ambas rutas
- Procedimientos de failover automático
## 🚨 Procedimientos de Rollback
### Escenario 1: Fallo en Unión al Dominio
1. Desunir equipo del dominio usando credenciales locales administrativas
2. Restaurar configuración de red original
3. Recuperar perfiles de usuario desde backup
4. Revertir cambios en DNS y configuración de red
### Escenario 2: Problemas de Conectividad Persistente
1. **Prioridad 1:** Diagnosticar comunicación directa local
- Verificar configuración IP local
- Revisar reglas de firewall del router ISP
- Probar conectividad básica entre dispositivos
2. **Prioridad 2:** Habilitar acceso alternativo via Tailscale + RustDesk
3. **Prioridad 3:** Configurar acceso directo temporal si es necesario
4. **Prioridad 4:** Escalar diagnóstico a nivel de infraestructura de red
### Escenario 3: Fallo en Comunicación Directa Local
1. Activar automáticamente ruta Tailscale como primaria
2. Diagnosticar problemas de red local (router ISP, firewall, DHCP)
3. Reconfigurar IPs locales si es necesario
4. Verificar que ambos dispositivos estén en misma subred física
### Escenario 4: Fallo en Sistema DASUTEN
1. Revertir a VM de pruebas `pcv-dasu0` para operaciones críticas
2. Mantener acceso local a datos si es necesario
3. Ejecutar procedimientos de recuperación documentados
## 🔧 Notas Técnicas
### Configuración de Red Requerida (ACTUALIZADA)
#### Configuración Local (PRIMARIA)
```
Adaptador de Red pc-dasu0 (Local):
- IP: [DHCP o estática según subred del router ISP]
- Máscara: [Según configuración router]
- Gateway: [Router ISP local]
- DNS Primario: 10.0.100.10 (dc-dasuten) via ruta local
- DNS Secundario: 8.8.8.8 (fallback)
- Suffix DNS: dasuten.utnlr
```
#### Configuración Tailscale (BACKUP)
```
Tailscale en pc-dasu0:
- IP Tailscale: 100.65.62.44
- Ruta a 10.0.100.0/24: via srv-dasu (100.116.210.36)
- Subnet Router: srv-dasu
```
### Procedimientos para Comunicación Directa Local
#### Paso 1: Identificación de IPs Locales
```powershell
# En pc-dasu0
ipconfig /all
# Identificar IP local asignada por router ISP
# En srv-dasu (via SSH)
ip addr show
# Identificar IP local en interfaz física
```
#### Paso 2: Prueba de Conectividad Básica
```powershell
# Desde pc-dasu0 hacia srv-dasu (IP local)
ping [IP-local-srv-dasu]
Test-NetConnection -ComputerName [IP-local-srv-dasu] -Port 22
# Desde srv-dasu hacia pc-dasu0 (IP local)
ssh user@srv-dasu "ping [IP-local-pc-dasu0]"
```
#### Paso 3: Configuración de Firewall Local
```powershell
# Permitir puertos de dominio en firewall de Windows
New-NetFirewallRule -DisplayName "Dominio DASUTEN" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 389,636,3268,3269,445 `
-Action Allow `
-RemoteAddress [Subred-local]/24
```
### Puertos Críticos para Validación
- **TCP 389/636**: LDAP/LDAPS para autenticación de dominio
- **TCP 3268/3269**: Global Catalog
- **TCP 445**: SMB para recursos compartidos
- **TCP 135, 137-139, 445**: NetBIOS/SMB
- **UDP 123**: NTP para sincronización de tiempo
- **TCP 22**: SSH para administración de srv-dasu
### Dependencias Clave (ACTUALIZADAS)
1. **Router ISP Funcional**: Debe permitir comunicación entre dispositivos locales
2. **Comunicación Local**: Configuración correcta de IPs en misma subred
3. **Firewall Local**: Reglas que permitan puertos de dominio entre dispositivos
4. **Tailscale Subnet Router**: `srv-dasu` debe exponer `10.0.100.0/24` (backup)
5. **DNS Funcional**: `dc-dasuten` debe resolver nombres internos y externos
6. **Sincronización de Tiempo**: NTP configurado entre todos los nodos
7. **Credenciales**: Acceso a bóveda `ns8-candados` para `admindasu`
## 📊 Métricas de Éxito (ACTUALIZADAS)
1. **Conectividad Local**: Ping exitoso >99% del tiempo a `srv-dasu` via IP local
2. **Conectividad Dominio**: Ping exitoso >95% del tiempo a `dc-dasuten` (`10.0.100.10`)
3. **Autenticación**: Login en dominio exitoso en <15 segundos via ruta local
4. **Latencia**: <5ms en comunicación local entre `pc-dasu0` y `srv-dasu`
5. **Sistema DASUTEN**: Acceso completo y operativo al sistema productivo
6. **Estabilidad**: 0 incidentes críticos en primeras 72 horas post-implementación
7. **Usuario**: Perfiles migrados exitosamente sin pérdida de datos
8. **Resiliencia**: Failover automático a Tailscale en <30 segundos si falla ruta local
## 📚 Referencias
1. [Proyecto P2601 DASUTEN](../../P2601_dasuten.md)
2. [Nodo: pc-dasu0](../nodos/pc-dasu0.md)
3. [Nodo: pcv-dasu0](../nodos/pcv-dasu0.md) *(VM de referencia)*
4. [Nodo: dc-dasuten](../nodos/dc-dasuten.md)
5. [Nodo: srv-dasu](../nodos/srv-dasu.md)
6. [Plan 6.1.A: Red srv-dasu](P2601_6.1.A - Red_SrvDasu.md)
7. [ADN: Seguridad y Red](../adn/03_seguridad.md)
8. **NUEVO:** [Procedimiento de Comunicación Directa Local](../proc/P2601_6.1.B_comunicacion_directa_local.md)
---
## 📋 Registro de Diagnósticos
### 15/03/2026 — Diagnóstico remoto via `./adn/tools/run ssh`
**Herramienta:** CLI `ssh` (P2604-S11, nueva herramienta ADN reutilizable)
| Nodo | Puerto 7022 | Ping | Estado |
|:-----|:-----------:|:----:|:------:|
| srv-dasu | SSH:22 ✅ | ✅ ~95ms via Tailscale | Online (uptime 4d) |
| dc-dasuten | ❌ Cerrado | ❌ timeout | VM apagada o sin SSH |
| sql-dasuten | ✅ Abierto | - | Accesible via proxy srv-dasu |
| pcv-dasu0 | ✅ Abierto | - | Accesible via proxy srv-dasu |
| pc-dasu0 | - | ❌ Offline Tailscale | Offline hace 1d |
**Conclusión:** `sql-dasuten` y `pcv-dasu0` están activas y accesibles. `dc-dasuten` requiere atención (encender VM o verificar SSH).
---
**⚠️ ADVERTENCIA CRÍTICA:** Este plan sigue la filosofía DB-First del ADN.
**🔍 CAMBIO FUNDAMENTAL:** La topología de red compartida (mismo router ISP) cambia radicalmente la estrategia de conectividad, priorizando comunicación directa local sobre soluciones de tunelización como Tailscale. Esto representa una optimización significativa en performance y estabilidad.
+5 -2
View File
@@ -20,8 +20,11 @@
- **Subred Aislada**: `10.0.100.0/24` - **Subred Aislada**: `10.0.100.0/24`
- **IP**: `10.0.100.10/24` (Estática oculta tras NAT de Proxmox) - **IP**: `10.0.100.10/24` (Estática oculta tras NAT de Proxmox)
- **Gateway**: `10.0.100.1` (IP de ruteo del host Proxmox) - **Gateway**: `10.0.100.1` (IP de ruteo del host Proxmox)
- **Servidores DNS**: `127.0.0.1` / `8.8.8.8` - **Servidores DNS**: `10.0.100.10` (local), `8.8.8.8` (backup)
- **Acceso Remoto**: RDP Habilitado (TCP 3389) - **Acceso Remoto**:
- RDP Habilitado (TCP 3389)
- SSH Habilitado (Puerto 22, 7022)
- Tailscale: Activo
## Servicios y Roles ## Servicios y Roles
1. **Active Directory Domain Services (AD DS)** 1. **Active Directory Domain Services (AD DS)**
+1
View File
@@ -26,6 +26,7 @@
- **Acceso Remoto**: - **Acceso Remoto**:
- **SSH**: `DASUTEN\admindasu@10.0.100.11:7022` (Password, Bóveda: `admindasu`) - **SSH**: `DASUTEN\admindasu@10.0.100.11:7022` (Password, Bóveda: `admindasu`)
- OpenSSH Server (Puerto 7022) - ✅ Habilitado - OpenSSH Server (Puerto 7022) - ✅ Habilitado
- **Tailscale**: Activo
- SQL Browser (UDP 1434) - SQL Browser (UDP 1434)
- SQL Instance (TCP 1433) - SQL Instance (TCP 1433)
@@ -30,6 +30,21 @@ module.exports = (pool) => {
res.json(rows.map(r => r.fecha)); res.json(rows.map(r => r.fecha));
}); });
// GET /api/bitacoras/:fecha/version — Devuelve el ID max de entradas para smart refresh
router.get('/:fecha/version', async (req, res) => {
const { fecha } = req.params;
const bResult = await pool.query('SELECT id FROM bitacoras.bitacoras WHERE fecha = $1', [fecha]);
if (bResult.rows.length === 0) {
return res.json({ max_id: 0, count: 0 });
}
const bitacoraId = bResult.rows[0].id;
const { rows } = await pool.query(`
SELECT COALESCE(MAX(id), 0) as max_id, COUNT(*) as count
FROM bitacoras.entradas WHERE bitacora_id = $1
`, [bitacoraId]);
res.json(rows[0]);
});
// GET /api/bitacoras/:fecha/completa — Bitácora completa con entradas agrupadas por nodo // GET /api/bitacoras/:fecha/completa — Bitácora completa con entradas agrupadas por nodo
router.get('/:fecha/completa', async (req, res) => { router.get('/:fecha/completa', async (req, res) => {
const { fecha } = req.params; const { fecha } = req.params;
@@ -285,8 +285,54 @@ function App() {
setSelectedProyecto(proyectos[nextIndex].codigo); setSelectedProyecto(proyectos[nextIndex].codigo);
}; };
// Auto-refresh inteligente: solo actualizar si hay cambios
const [lastVersion, setLastVersion] = useState<{ max_id: number; count: number } | null>(null);
const fetchBitacoraVersion = useCallback(async () => {
try {
const res = await fetch(`${API_URL}/bitacoras/${fecha}/version`);
return await res.json();
} catch { return null; }
}, [fecha]);
const smartRefresh = useCallback(async () => {
const newVersion = await fetchBitacoraVersion();
if (!newVersion) {
fetchBitacora();
fetchFechasActivas();
return;
}
if (!lastVersion || newVersion.max_id !== lastVersion.max_id || Number(newVersion.count) !== Number(lastVersion.count)) {
setLastVersion(newVersion);
fetchBitacora();
fetchFechasActivas();
}
}, [fetchBitacoraVersion, fetchBitacora, fetchFechasActivas, lastVersion]);
useEffect(() => { fetchBitacora(); }, [fetchBitacora]); useEffect(() => { fetchBitacora(); }, [fetchBitacora]);
useEffect(() => { fetchNodos(); fetchProyectos(); fetchFechasActivas(); }, []); useEffect(() => { fetchNodos(); fetchProyectos(); }, []);
useEffect(() => { fetchFechasActivas(); }, [fetchFechasActivas]);
// Inicializar versión al cargar
useEffect(() => {
fetchBitacoraVersion().then(v => { if (v) setLastVersion(v); });
}, [fetchBitacoraVersion]);
// Auto-refresh cada 30 segundos (solo si hay cambios)
useEffect(() => {
const interval = setInterval(smartRefresh, 30000);
// También actualizar cuando la página recupera el foco
const handleVisibility = () => {
if (!document.hidden) smartRefresh();
};
document.addEventListener('visibilitychange', handleVisibility);
return () => {
clearInterval(interval);
document.removeEventListener('visibilitychange', handleVisibility);
};
}, [smartRefresh]);
// Rebuild calendar view month when fecha changes // Rebuild calendar view month when fecha changes
useEffect(() => { useEffect(() => {