Agente · dev-terminal
Propósito
Desarrollo y mantenimiento del Terminal Hub, el Local Agent y el sistema Multi-Pane de CreaRack-Pro.
Cubre la app terminal/, los 10 módulos JS del terminal y el ejecutable Windows CreaRackAgent.exe.
Módulos JS (terminal/)
static/js/terminal/
├── TabManager.js # Gestión de pestañas SSH
├── MultiPaneManager.js # Layouts CSS Grid (1x1, 2x1, 1x2, 2x2, 3x1)
├── TerminalToolbar.js # Toolbar SSH (tema, tamaño, color, clipboard)
├── TerminalSettings.js # Preferencias de usuario
├── ClusterMode.js # Broadcast multi-sesión simultánea
├── AgentLifecycle.js # Activación y estado del Local Agent
├── ManualConnection.js # Conexiones manuales sin device
├── DeviceManager.js # Filtros y grupos (patrón HTMX)
└── index.js # Re-exports
App Django: terminal/
terminal/
├── api.py # Endpoints Django Ninja
├── views.py # Vista terminal_view
├── consumers.py # WebSocket consumers (SSH bridge)
├── routing.py # WebSocket routing
└── agent/ # Local Agent (Windows exe)
├── local_agent.py # FastAPI app principal
├── models.py # Pydantic request/response models
├── ssh_bridge.py # SSHBridge: conexiones SSH persistentes
├── scrapli_manager.py # LocalScrapliManager: multi-vendor
├── cluster_engine.py # ClusterEngine: ejecución paralela
├── network_utils.py # Ping, scan, discovery, ARP
├── auth_manager.py # DPAPI + JWT authentication
├── offline_cache.py # SQLite cache offline
├── sentinel_scheduler.py # Loops async ping/SNMP/HTTP
├── sync_manager.py # REST push métricas a SaaS
├── saas_connector.py # WebSocket persistente al SaaS
├── timeseries_store.py # SQLite WAL store métricas Sentinel
├── monitoring_service.py # Workers de monitoreo
├── installer.py # Always-reinstall strategy
├── windows_integration.py # Registro Windows, auto-start
├── logging_handler.py # MemoryLogHandler + WS broadcast
├── version.py # AGENT_VERSION — fuente de verdad
└── assets/
├── terminal.html # UI xterm.js + Asteroids
├── debug.html # Tools Hub (3 tabs, 7 herramientas)
└── oui_vendors.json # MAC vendors DB (~230 entries)
Local Agent — arquitectura general
El agente es un ejecutable Windows standalone (~25MB) que actúa como puente entre el navegador y los dispositivos de red con IPs privadas.
[Navegador/SaaS] ←──WebSocket──► [CreaRackAgent.exe :5050] ←──SSH──► [Dispositivos 192.168.x.x]
Instalación: %APPDATA%\CreaRackAgent\
Puerto: 5050 (solo localhost — no accesible desde la red)
Auto-start: Scheduled task de Windows
Distribución: GitHub Releases (NO en el repo git)
https://github.com/CreaRackSL/CreaRack-Pro/releases/latest/download/CreaRackAgent.exe
Multi-Agent Fleet (Primary/Secondary)
| Rol | Función |
|---|---|
| Primary | Ejecuta Sentinel (SNMP, ping, HTTP monitoring 24/7) · Solo uno por tenant |
| Secondary | Solo SSH/herramientas · No ejecuta Sentinel |
- Asignación automática: primer agente que conecta = Primary
- Failover: si Primary se desconecta, Secondary más antiguo se promueve
- Rol persistido en SQLite local (
agent_roleen tabla config) - Solo Primary hace auto-resume de Sentinel al reiniciar
Fleet API endpoints (SaaS):
GET /api/agent/fleet # Lista agentes del tenant
POST /api/agent/fleet/{id}/promote # Promover a Primary
POST /api/agent/fleet/{id}/demote # Degradar a Secondary
GET /api/agent/fleet/config # Role Assignment Mode (auto/manual)
POST /api/agent/fleet/config # Cambiar modo
POST /api/agent/fleet/{id}/reauth # Regenerar JWT frescos
Agent endpoints (localhost:5050):
GET /agent/role # Rol actual y estado Sentinel
GET /info # Versión, uptime, sessions, role
GET /health # {"status": "healthy"}
Terminal SSH
WebSocket protocol
// Conectar
ws.send(JSON.stringify({
action: "connect",
host: "192.168.1.1", port: 22,
username: "admin", password: "secret"
}));
// Enviar datos
ws.send(JSON.stringify({ action: "data", data: "show version\r\n" }));
// Respuestas del servidor
// { type: "output", data: "..." }
// { type: "status", message: "..." }
// { type: "error", message: "..." }
Persistencia de sesiones SSH
Las sesiones SSH sobreviven a la navegación entre páginas:
| Escenario | Comportamiento |
|---|---|
| Navegar fuera y volver | Reattach automático — replay output_buffer (2000 chunks) + “SESSION RESTORED” |
| SSH expirado (timeout remoto) | Detecta ssh_conn=None, limpia bridge stale, crea sesión nueva |
| Cerrar pestaña | Sesión SSH sigue viva en Agent hasta que el servidor la cierre |
Flujo de reattach:
- iframe carga
terminal.htmly abre WS/ws/terminal/{sid} - Agent detecta
sidenACTIVE_BRIDGES, verificassh_conn+ssh_process - SSH vivo → envía
output_buffer→ “Tunnel Established!” - SSH muerto → limpia bridge stale → nueva sesión
- Frontend consulta
GET /terminal/sessionsantes de enviarCONNECT_SSH
Temas disponibles
| Tema | Fondo | Descripción |
|---|---|---|
| Campbell | #0C0C0C | Default Windows Terminal |
| Gruvbox Dark | #282828 | Retro cálido |
| Green Screen | #001100 | Terminal verde fosforescente |
| Tango Dark | #000000 | Paleta GNOME clásica |
Atajos de teclado
| Atajo | Acción |
|---|---|
Ctrl+C | Copiar selección (si hay) o enviar SIGINT |
Ctrl+V | Pegar desde clipboard |
Ctrl+Shift+C/V | Copiar/pegar siempre |
El iframe requiere
allow="clipboard-read; clipboard-write"para Clipboard API en Chrome 2024+.
Syntax highlighting (colores ANSI)
Toggle “Color” en toolbar. Dos capas:
Keywords:
| Color | Palabras |
|---|---|
| Rojo | error, fail, failed, critical, down, refused |
| Verde | up, ok, success, connected, online, active |
| Amarillo | warning, alert, timeout, deprecated |
| Cian | IPs IPv4 |
| Dorado | MACs (AA:BB:CC:DD:EE:FF) |
Banner (malva/magenta): versiones, copyright, URLs, fabricantes (Cisco, Juniper, Arista, Xirrus, Cambium…), avisos NOTICE/IMPORTANT.
Keywords usan
\b(word boundaries) — “support” no colorea “up” accidentalmente.
Superpersistencia de ajustes
localStorage key crearack_terminal_settings:
- Tema y tamaño (L=22px, M=18px, B=14px)
- Se restauran en cada nueva pestaña y tras recargar página
Multi-Pane Layouts
5 layouts CSS Grid gestionados por MultiPaneManager.js:
| Layout | Descripción |
|---|---|
| 1x1 | Una sola terminal |
| 2x1 | Dos terminales en fila |
| 1x2 | Dos terminales en columna |
| 2x2 | Cuatro terminales |
| 3x1 | Tres terminales en fila |
- Drag-to-resize entre paneles
- Shared toolbar para controles comunes
- Grid tab grouping
Cluster Mode
Ejecución de comandos/scripts en múltiples dispositivos simultáneamente.
Vendors soportados (Scrapli):
| Vendor | Platform ID |
|---|---|
| Cisco IOS/IOS-XE | cisco_ios, cisco_iosxe |
| Cisco NX-OS | cisco_nxos |
| Arista EOS | arista_eos |
| Juniper JunOS | juniper_junos |
| Genérico SSH | generic |
Cluster endpoints (Agent :5050):
POST /cluster/execute # Comando en múltiples dispositivos
POST /cluster/script # Script en múltiples dispositivos
POST /cluster/health # Verificar conectividad múltiple
POST /cluster/backup # Backup de múltiples dispositivos
POST /execute/single # Comando en un solo dispositivo
Sentinel Mode (monitoreo 24/7)
Solo el Primary ejecuta Sentinel. Loops async independientes:
| Loop | Archivo | Intervalo | Métricas |
|---|---|---|---|
| Ping | sentinel/ping.py | Configurable | latencia, packet loss |
| SNMP Bandwidth | sentinel/snmp_bandwidth.py | 60s | In/Out Mbps, errors, discards |
| SNMP Extras | sentinel/snmp_extras.py | Configurable | métricas adicionales |
| HTTP Check | sentinel/http_check.py | Configurable | status code, response time |
SNMP Bandwidth — 8 OIDs por target:
- ifHCInOctets / ifHCOutOctets (Counter64, preferidos)
- ifInOctets / ifOutOctets (Counter32, fallback)
- ifInErrors / ifOutErrors
- ifInDiscards / ifOutDiscards
HC→Legacy fallback: si ifHCInOctets delta = 0 pero ifInOctets delta > 0, usa legacy (necesario para Xirrus APs). Spike protection: rates >10 Gbps descartados y baseline reseteado.
SQLite buffering (metrics.db):
- Triple retention: synced >48h | snmp_fast_* >7d | unsynced >30d
- Auto-purge para mantener ~50MB steady-state
Protocolo WebSocket SaaS ↔ Agent
SaaS → Agent:
| Tipo | Payload |
|---|---|
START_MONITORING | {targets: [...]} |
STOP_MONITORING | — |
UPDATE_TARGETS | {targets: [...]} |
PING_NOW | {target_id: X} |
GET_STATUS | — |
Agent → SaaS:
| Tipo | Payload |
|---|---|
AGENT_HELLO | {agent_id, version, capabilities} |
METRICS | {batch: [{target_id, metric_type, value, timestamp}]} |
HEARTBEAT | {timestamp, sentinel_active} — cada 30s |
ALERT | {target_id, alert_type, message} |
STATUS | {state, targets_count, uptime} |
Autenticación JWT (Zero-Intervention)
Tres capas de protección para tokens:
| Capa | Mecanismo | Cuándo actúa |
|---|---|---|
| Layer 1 | Proactive refresh (75% lifetime) | Token al 75% de vida (~54h) |
| Layer 2 | SaaS WS push (<2h remaining) | Token <2h restantes |
| Layer 3 | Auto-reauth via DPAPI credentials | Ambos tokens expirados |
- Access token TTL: 72h (sobrevive fines de semana)
- Refresh token TTL: 180d (sobrevive vacaciones)
- Credenciales cifradas con Windows DPAPI
Tools Hub (localhost:5050)
3 tabs: Status | Tools | Debug
7 herramientas de red (Tools tab):
| # | Herramienta | Endpoint |
|---|---|---|
| 1 | Port Check | GET /check?host=X&port=Y |
| 2 | ICMP Ping | GET /network/ping-icmp?host=X |
| 3 | DNS Lookup | GET /network/hostname?ip=X |
| 4 | SSH Banner | GET /network/banner?host=X&port=Y |
| 5 | ARP Table | GET /network/arp-table |
| 6 | Network Discovery | POST /network/discover |
| 7 | Port Scan | POST /network/scan |
Debug Console:
- Logs en tiempo real via WS
/ws/debug - Altura dinámica
calc(100vh - 320px) - Colores por nivel: ERROR (rojo), WARNING (amarillo), INFO (azul), DEBUG (gris)
- Toolbar: Pause/Resume · Copy All · Download (.txt) · Clear
- Filtros por nivel + búsqueda con highlight
Sleep/Wake Recovery (Windows)
Tras suspender/hibernar Windows, el Agent se recupera en <15 segundos:
SLEEP_DETECTION_THRESHOLD = 120s- Reset automático de circuit breaker
- Limpieza de SNMP baselines (evita delta corrupto)
- Espera 3s para estabilización de NIC
Compilación
cd C:\dev\CreaRack-Pro
build_agent.bat
# Resultado: static/downloads/CreaRackAgent.exe (~25MB)
Imports condicionales (frozen vs dev):
if getattr(sys, "frozen", False):
from models import DeviceTarget # frozen (.exe)
else:
from .models import DeviceTarget # desarrollo
Detección de IP privada (frontend)
function isPrivateIPAddress(ip) {
const parts = ip.split('.').map(Number);
if (parts[0] === 10) return true; // 10.0.0.0/8
if (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) return true; // 172.16.0.0/12
if (parts[0] === 192 && parts[1] === 168) return true; // 192.168.0.0/16
if (parts[0] === 127) return true; // localhost
return false;
}
Convenciones y restricciones
- El Agent solo escucha en
127.0.0.1:5050— nunca exponer externamente - CORS configurado con
allow_origins=["*"]— no cambiar sin análisis de seguridad version.pyes la única fuente de verdad paraAGENT_VERSIONDeviceFilterServicecentraliza el filtrado del sidebar — no duplicar en Terminal- Persistencia de ajustes: localStorage key
crearack_terminal_settings - Distribución del .exe: siempre via GitHub Releases, nunca en el repo git
Véase también
- [[concept—terminal—local-agent]] — arquitectura del Local Agent
- [[crearack-tech—backend—local-agent]] — backend del Local Agent
- [[crearack-tech—admin—local-agent]] — admin del Local Agent
- [[crearack-tech—guides—local-agent-guide]] — guía de debugging del Local Agent
- [[crearack—terminal—que-es-terminal]] — introducción al Terminal Hub
- [[crearack—terminal—sesiones-ssh]] — sesiones SSH desde el Terminal
- [[crearack—terminal—local-agent]] — Local Agent desde el usuario
- [[entity—terminal—model—agentinstance]] — instancia de Local Agent registrada
Referenciado desde
- Agente · dev-backend
- Agente · dev-frontend
- Agente · dev-qa
- Agente · legal-rgpd
- Agente · marketing-content
- Agente · ops-infra
- Agente · ops-workspace
- Agente · support-l1
- CreaRack Local Agent - Guía Completa
- Distribucion del Agente Local - CreaRackAgent.exe
- Hotfix 2.21.4: la "autocuración" del motor SNMP era un diagnóstico equivocado
- Hotfix 2.21.5: un walk SNMP vencido por timeout fabricaba un 0 (Regla 13) — 47 APs con dato falso 30 días
- Incidente 24-08-2026 · el cortacircuitos mixto silenció el SNMP vivo del CCIB 15 minutos
- Incidente 24-08-2026 · el motor SNMP quedaba corrupto tras cuelgues seguidos — timeout duro + autocuración (Agente 2.21.2→2.21.3)
- Incidente: la rotación de agent.log nunca funcionó en el binario compilado (WinError 32)
- Local Agent - Debugging & Diagnostics Guide