CreaRack-SL

Subida de MIBs personalizados se encola en Huey — 202 + job_id (v1.89.0)

Funcionalidadactivecreado Mon Aug 31#network#huey#django#security#performance#adr-t2#async

Para qué sirve

Subir un fichero MIB de un fabricante (el “diccionario” que traduce los códigos SNMP de un equipo a nombres legibles) ya no bloquea la respuesta del servidor mientras se compila. El usuario sigue subiendo el fichero igual que siempre desde el asistente de Auto-Provision o la ficha de un dispositivo; por debajo, la compilación pasa a un trabajador de fondo y la pantalla espera el resultado con un pequeño sondeo, igual que ya pasa con Auto-Plan o la copia de seguridad completa.

Por qué — el problema que resuelve

POST /api/network/vendor-profiles/{slug}/upload-mib compilaba el fichero con pysmi dentro del propio request. Una MIB real de fabricante no es trivial: la XIRRUS-MIB pesa 583 KB y expone 1.736 OIDs, y compilarla son varios segundos de un worker ASGI bloqueado — el mismo síntoma que ya tenían Auto-Plan y el backup completo antes de migrar (ver [[concept—general—que-operaciones-sincronas-se-ejecutan-en-el-reques]], que ya citaba upload_mib como candidato en su título). Es el hallazgo MEDIA de la sub-área network-sa3 de la Auditoría Suprema.

Cómo funciona ahora

El endpoint conserva TODA la validación barata — permiso admin, límite de 20 subidas/hora, tamaño máximo 2 MB, extensión permitida, nombre de módulo válido y su guarda anti path-traversal — y sigue guardando el fichero fuente en disco. Lo único que cambia es el final: en vez de compilar ahí mismo, crea un AsyncJob (nuevo tipo AsyncJob.Kind.MIB_UPLOAD, migración core/0033) y encola network.tasks.run_mib_upload(job_id, org_id, slug, module_name, source_path, ...), respondiendo 202 + job_id en vez de 200 con el MIB ya compilado. Como el job cuelga de una organización con aislamiento por tenant (RLS), el endpoint ahora exige contexto de organización ANTES de encolar — si no hay org, corta con 400 en vez de dejar un job huérfano.

run_mib_upload (en network/tasks.py) hace el trabajo que antes hacía el endpoint: compila con pysmi, extrae los OIDs (con el mismo fallback a parseo directo del ASN.1 si pysmi no traga el fichero — sigue siendo un modo soportado, no un error a medias), y publica el CustomMib resultante en el result del job, con la MISMA forma que devolvía el endpoint síncrono. El frontend sondea con el nuevo helper ApiService.pollJob() contra [[entity—core—endpoint—jobs-polling]].

Infraestructura — requiere redeploy del worker

compose.prod.yml montaba el volumen mib_cache solo en el servicio web. Sin ese montaje en worker, el .py compilado por pysmi caería en un sistema de ficheros que web no lee. El commit añade el volumen y MIB_CACHE_DIR también al worker — este cambio no tiene efecto hasta que se redeploye el worker, no solo web.

Tests

tests/network/test_mib_upload_async.py (nuevo, 185 líneas). El mismo commit incluye un fix de CI: el runner no tiene /app/mib_cache (esa ruta solo existe dentro de Docker), así que config/settings/test.py apunta MIB_CACHE_DIR a un directorio temporal para que el test reproduzca el entorno real.

Commits relacionados

  • 17df12e7 (2026-08-31) — PR #475, v1.89.0.

Véase también

  • [[concept—infra—async-job-pattern]]
  • [[concept—general—que-operaciones-sincronas-se-ejecutan-en-el-reques]]
  • [[entity—core—model—asyncjob]]
  • [[entity—core—endpoint—jobs-polling]]
  • [[feature—monitoring—targets-provisioning-async]]
  • [[feature—racks—backup-restore-async-v156]]
  • [[crearack—network—mibs-and-vendor-profiles]]