Volver a la wiki

Endpoint: GET/POST/DELETE /auto-provision/scans

Descripción

Endpoint REST que persiste las búsquedas guardadas de Auto-Provision en BD, reemplazando el localStorage del navegador. Accesible en tres métodos: listado, creación y borrado.

Ubicación: network/api/scan_sessions.py (router registrado en network/api/__init__.py)

Operaciones

GET /auto-provision/scans

Permisos: network.view (RLS)

Respuesta:

[
  {
    "id": 42,
    "name": "10.0.0.0/24",
    "created_at": "2026-06-08T14:05:00Z",
    "device_count": 5,
    "profile_ids": [12, 13, 14, 15, 16]
  },
  ...
]

Comportamiento:

Códigos HTTP:


POST /auto-provision/scans

Permisos: network.edit (RLS)

Request:

{
  "name": "10.0.0.0/24",
  "profile_ids": [12, 13, 14]
}

Respuesta (200 OK):

{
  "id": 43,
  "name": "10.0.0.0/24",
  "created_at": "2026-06-08T14:06:00Z",
  "device_count": 3,
  "profile_ids": [12, 13, 14]
}

Comportamiento:

  1. Validación de permisos: requiere network.edit.
  2. Sanitización de name: recorta espacios en blanco, limita a 255 caracteres; default “Untitled scan” si queda vacío.
  3. Filtrado de perfiles: solo acepta IDs de DeviceProfile que pertenecen a la org del usuario. Perfiles de otros tenants se descartan silenciosamente (sin error).
  4. Creación: inserta el registro con created_by = usuario actual (NULL si es JWT/anónimo).
  5. Poda automática: si la org ya tiene ≥20 búsquedas, borra las más antiguas, manteniendo solo 20 recientes.
  6. Auditoría: llama a log_action(request, "NETWORK", "auto_provision.scan_saved", name).
  7. Respuesta: retorna la sesión creada con prefetch de perfiles.

Códigos HTTP:


DELETE /auto-provision/scans/{session_id}

Permisos: network.edit (RLS)

Respuesta (200 OK):

{"success": true}

Respuesta (404 Not Found):

{"error": "Scan session not found"}

Comportamiento:

  1. Requiere network.edit.
  2. Intenta eliminar el registro session_id cuya organization coincida con la del usuario (RLS).
  3. Si no existe o pertenece a otra org, retorna 404.
  4. Si existe y es de la org, lo borra y retorna 200.

Códigos HTTP:


Esquemas Ninja

ScanSessionOut (Schema)

Respuesta serializada de lectura.

class ScanSessionOut(Schema):
    id: int
    name: str
    created_at: datetime
    device_count: int  # Calculado en vivo desde profiles.all()
    profile_ids: list[int]  # Lista de IDs de DeviceProfile

ScanSessionCreate (Schema)

Payload esperado en POST.

class ScanSessionCreate(Schema):
    name: str  # Etiqueta del escaneo
    profile_ids: list[int] = []  # Perfiles asociados (default vacía)

Integración con el Frontend

Archivo: static/js/network/auto_provision/sessions.js


Constantes

NombreValorDescripción
MAX_SESSIONS20Máximo de búsquedas por org
SCANS_API (JS)/api/network/auto-provision/scansURL base del endpoint

Manejo de Errores

EscenarioHTTPRespuesta
Usuario sin org (raro)400{"error": "No organization found"}
Borrar búsqueda de otra org404{"error": "Scan session not found"}
GET con usuario sin org200[] (vacío)
POST con perfil de otra org200Se crea, pero perfil se descarta (silent)

Auditoría y Logs


Tests

Archivo: tests/api/test_network_scan_sessions.py

Cubre:


Historial

Véase también

Subir