CreaRack-SL

Local Agent v2.x

Conceptoactiveverificado Fri Jul 10#terminal#agent#jwt#websocket#sentinel#failover

Local Agent

Nota (2026-07): el título original de esta página era “Local Agent v2.x” (snapshot de abril-2026). El número de versión NO se ancla aquí: la fuente de verdad es terminal/agent/version.py (AGENT_VERSION). Actualizaciones de contexto respecto a aquel snapshot: (1) el auto-update desatendido está operativo (paquetes firmados Ed25519 + bootstrap onedir, sin Authenticode); (2) el Agente es “Full-Local” — TODA la I/O de red hacia dispositivos del cliente pasa por el Agente, no solo la monitorización. La arquitectura JWT/WS/Sentinel descrita abajo sigue vigente.

Qué es

Proceso Python autónomo que se instala en la red del cliente y mantiene WebSocket persistente con el SaaS. Es “Full-Local”: toda la I/O de red hacia dispositivos del cliente (SSH/SFTP, discovery/SNMP, monitorización, deploy de Signage) pasa por él. Ejecuta monitorización activa (ping, SNMP, HTTP) sobre dispositivos locales y envía métricas/alertas al SaaS en tiempo real. Cada tenant puede tener múltiples agentes: uno opera como Primary y el resto como Secondary, garantizando continuidad ante fallos.

Por qué existe

El SaaS no tiene acceso directo a redes privadas de clientes. El agente resuelve la brecha: vive dentro del segmento, alcanza IPs no enrutables desde internet y actúa como proxy de telemetría. Diseño Primary/Secondary permite HA sin coordinación manual: si el Primary cae, el Secondary más antiguo es promovido automáticamente.

Componentes

JWT Auth (3 capas): al registrarse, agent obtiene access_token (72h, HS256) y refresh_token (180d) vía terminal/api/auth.py. Verificación en AgentConsumer.connect(): si agent_id del token no coincide con URL, rechaza con código 4002. Cuando token tiene <2h de vida, SaaS lo renueva proactivamente via WS con mensaje token_refresh (capa 2). Capa 3: POST /api/agent/reauth-self usando solo agent_id+tenant_id, rate limit 5 intentos/hora.

SaaSConnector (WS cliente) (terminal/agent/saas_connector.py): conexión saliente a wss://<saas>/ws/agent/<agent_id>/?token=<jwt>. Heartbeat cada 30s (ping/pong), timeout recv 90s para detectar TCP muertas tras NAT. Reconexión con backoff exponencial: 1s inicio, 60s máx, 2×. Handlers por nombre de comando (update_targets, enable_sentinel, set_role).

AgentConsumer (WS servidor) (terminal/consumers.py): extremo SaaS por conexión. Diccionario memoria ACTIVE_AGENTS. Al conectar, agent se registra en AgentInstance y recibe rol. last_seen actualiza máx 1 vez/30s para no saturar BD. Métricas escritas a VictoriaMetrics via MetricsWriter; tipos snmp_fast_*, snmp_extras_*, snmp_bandwidth_* reenviados en tiempo real al navegador via Channel Layer.

Primary/Secondary: en modo auto (default), _register_and_assign_role() consulta si hay Primary activo para el tenant. Agent muerto: last_seen > 10 min. Agentes >24h offline eliminados como ghost. Si no hay Primary activo, agent entrante recibe primary; si no, secondary. Modo manual vía POST /api/agent/fleet/config (admins) congela roles.

SentinelScheduler (terminal/agent/sentinel/scheduler.py): orquesta 5 loops asíncronos: ping_loop, snmp_bandwidth_loop, extras_loop, fast_snmp_loop, purge_loop. Escalonado 3s entre arranques para evitar ráfagas tras reconexión/hibernación. Detección de suspensión: compara tiempo de reloj entre ticks con SLEEP_DETECTION_THRESHOLD; si salta, resetea circuit breakers y contadores base SNMP. Targets cargados desde SQLite local (TimeSeriesStore) para operación offline; al recibir update_targets del SaaS, persiste antes de actualizar memoria. Incluye CircuitBreaker por target y AnomalyDetector (CNS) que reporta via InsightReporter.

Cache offline: agent escribe métricas/alertas en SQLite cuando no hay conectividad. Al reconectar, pendientes se envían a POST /api/agent/metrics/bulk (hasta 5000/request), que escribe a VictoriaMetrics y reenvía al navegador.

Flujos

Register → Primary → targets → métricas → failover:

  1. Usuario descarga agent del SaaS; incluye access_token de POST /api/agent/register.
  2. Agent arranca SaaSConnector.connect(), establece WS, envía agent_status con version, hostname, sentinel state.
  3. _register_and_assign_role() evalúa fleet: si no hay Primary vivo, promueve al entrante y envía welcome con role=primary.
  4. Primary recibe enable_sentinel y update_targets con MonitoringTarget del tenant + OIDs de VendorProfile.
  5. SentinelScheduler.update_targets() persiste en SQLite local e inicia loops.
  6. Métricas: por WS (type: metrics) o HTTP bulk offline (/api/agent/metrics/bulk).
  7. Si Primary desconecta, _handle_disconnect_failover() promueve Secondary más antiguo (por connected_at), envía set_role primary, enable_sentinel, targets.
  • entity--terminal--model--agentinstance — modelo Django con estado, rol, last_seen.
  • entity--monitoring--model--monitoringtarget — targets enviados al Primary.
  • concept--monitoring--cns — detección de anomalías y reporting desde el agent.

Véase también

  • [[entity—terminal—model—agentinstance]]
  • [[entity—monitoring—model—monitoringtarget]]
  • [[concept—monitoring—cns]]