CreaRack-SL

Agente 2.29.0: resultados grandes por REST, protocolo authoritative y descubrimiento profundo troceado por bytes

User value

El Agente local (el programa que corre en la red del cliente y hace de puente entre sus equipos y CreaRack Pro) habla con el servidor por un canal WebSocket con un tope de tamaño de mensaje (~1 MiB, Daphne). La versión 2.29.0 (25-09-2026, mega-auditoría ronda 5) resuelve tres puntos donde ese tope o la fiabilidad del canal causaban fallos silenciosos: resultados de operaciones grandes que no llegaban nunca, el Agente creyendo que ya no vigila ningún equipo por un fallo transitorio del servidor, y un descubrimiento profundo masivo que se cortaba a mitad.

Resultados grandes por REST (E1-03)

Una copia de configuración u otra operación de equipo puede devolver un resultado de varios cientos de KB — más de lo que cabe en un mensaje WebSocket. Antes, esa respuesta simplemente no llegaba. Ahora:

  • El Agente 2.29.0 sube el resultado con POST /api/agent/device-ops/{request_id}/result (terminal/api/device_op_upload.py, nuevo router device_op_upload montado en agent_router), autenticado con su JWT de Agente (get_agent_from_request, igual que el resto de /api/agent/*).
  • Tope de cuerpo: 20 MiB (margen sobre los 16 MiB que el propio Agente permite para una copia de configuración).
  • Cierra la tarea por el mismo camino que el WebSocket (DeviceOpsBusMixin._settle_device_task), acotado al tenant_id del token — no puede cerrar una tarea de otra organización.
  • Por el WebSocket, el Agente manda solo una referencia (result_ref) en vez del resultado completo; si la subida REST falla, el error es explícito en vez de una tarea que se queda colgada.
  • Los Agentes 2.28.0 y anteriores no usan este endpoint — sin cambios para ellos.

Sigue el mismo patrón que [[decision—20260919—agente-reload-targets-rest-en-vez-de-subir-tope-websocket]]: cuando el WebSocket no da para el tamaño del payload, la respuesta no es subir el tope del socket, es sacar ESE tráfico a REST.

Protocolo authoritative: la lista de equipos vacía ya no apaga la vigilancia (B-53)

Antes, cualquier respuesta del servidor con una lista de equipos vacía hacía que el Agente dejara de vigilar todo — incluido un fallo transitorio de red o un bug del servidor. Desde la 2.29.0, la respuesta lleva un campo authoritative: true/false:

  • El Agente solo aplica una lista vacía (deja de vigilar) si authoritative: true — el servidor confirma explícitamente “esta organización no tiene equipos”.
  • Un fallo de red, un HTTP distinto de 200, o una lista vacía SIN el campo (servidor viejo, versión anterior) hacen que el Agente conserve la lista que ya tenía — igual que el comportamiento previo a esta versión, para no romper compatibilidad con servidores que aún no mandan el campo.

Descubrimiento profundo troceado por tamaño (E2-07)

Un lote de descubrimiento profundo (deep discovery) con muchos equipos y sus OIDs puede superar el tope de 1 MiB del WebSocket. Es un mecanismo DISTINTO — y en una capa distinta — al troceo por número de perfiles de [[feature—network—deep-discovery-batch-dispatch]] (que agrupa de tres en tres para no saturar el Agente de lecturas SNMP simultáneas): este troceo es por BYTES del mensaje, no por cantidad de tareas.

  • terminal/agent_registry.py::encode_ws_message calcula el tamaño real en bytes del JSON antes de enviarlo y lanza AgentMessageTooLarge si supera WS_MAX_MESSAGE_BYTES — antes solo lo comprobaba update_targets; cualquier otra orden grande fallaba dentro de Daphne con un error genérico.
  • chunk_deep_discover_tasks parte la lista de tareas en trozos que quepan (con margen de 4096 bytes para el sobre del mensaje).
  • send_deep_discover envía cada trozo como una orden deep_discover independiente; el Agente las procesa todas bajo el mismo job_key, así que varias órdenes del mismo lote se acumulan en el mismo trabajo (compatible con Agentes 2.28, que no cambian).
  • Una tarea que SOLA ya no cabe en un mensaje se salta (no arrastra a las demás) y dispatch_deep_discovery_batch responde partial con cuántas se enviaron y cuántas no.

Duración de las tandas SNMP en el latido (E2-06)

Cada bucle SNMP del Agente (fast/bandwidth/extras) apunta cuánto tarda su tanda y lo manda en el latido (health.snmp_cycle_*_s); el servidor lo guarda en AgentInstance.health y lo expone en la API de flota — visibilidad de rendimiento del Agente sin instrumentación nueva del lado servidor.

Build reproducible (A1-stack-python)

El ejecutable del Agente se compila desde un lock completo con hashes (terminal/agent/requirements-agent.lock, 44 dependencias, generado con uv desde requirements-agent.in, instalado con pip install --require-hashes). build_agent.bat crea un entorno virtual limpio en cada build y aborta si el Python no es 3.14.x. pip-audit escanea el lock completo. Los Agentes que se auto-actualizan siguen con las librerías de su instalación hasta que alguien los reinstala.

Commits relacionados

  • 11d687c404a1755c9dc0c86a30a9bdb87914efd3 (25-09-2026, PR #608, v1.160.0) — release que integra la rama edu/mega-agente-2290: T07 (resultados grandes REST + deep discovery troceado + SNMP timing), T30 (contrato de permisos del endpoint nuevo), B-53 (protocolo authoritative), build reproducible. AGENT_VERSION 2.28.0 → 2.29.0.

Véase también

  • [[entity—network—model—deviceprofile]]
  • [[feature—network—deep-discovery-batch-dispatch]]
  • [[feature—network—deep-discovery-batching]]
  • [[incident—20260907—ccib-comando-bloqueante-websocket]]
  • [[decision—20260919—agente-reload-targets-rest-en-vez-de-subir-tope-websocket]]
  • [[entity—monitoring—targetlistout-payload-slim]]