Volver a la wiki

Endpoint: Obtener y actualizar configuración de DeviceProfile

Descripción

Par de endpoints en network/api/assign.py para obtener y editar credenciales SNMP/SSH + asignación a grupos de un DeviceProfile (dispositivo descubierto automáticamente) desde el interfaz de monitorización.

Utilizados por el modal centralizado DeviceConfigModal en Observatory, Wireless, UPS y Digital Signage.

Endpoints

GET /api/network/auto-provision/profiles/{profile_id}/config

Propósito: Obtener configuración actual de un perfil para poblar el modal.

Autenticación: require_perm(request, "network", "view")

Parámetros:

Respuesta (200 OK):

{
  "id": <int>,
  "name": "<hostname o ip_address>",
  "ip_address": "<ip>",
  "snmp_community": "<community>",
  "snmp_version": "v2c | v3",
  "snmp_v3_username": "<username>",
  "snmp_v3_auth_protocol": "SHA | MD5 | ''",
  "snmp_v3_priv_protocol": "AES | DES | ''",
  "has_snmp_v3_keys": <bool>,  // flags: no retorna las claves
  "ssh_username": "<username>",
  "has_stored_ssh": <bool>,     // flag: no retorna el password
  "group_ids": [<int>, ...]
}

Errores:

Notas:

PUT /api/network/auto-provision/profiles/{profile_id}/config

Propósito: Actualizar credenciales y grupos de un perfil.

Autenticación: require_perm(request, "network", "edit")

Parámetros:

{
  "snmp_community": "<community> | null",
  "snmp_version": "v2c | v3 | null",
  "snmp_v3_username": "<username> | null",
  "snmp_v3_auth_protocol": "SHA | MD5 | null",
  "snmp_v3_auth_key": "<secret> | null",
  "snmp_v3_priv_protocol": "AES | DES | null",
  "snmp_v3_priv_key": "<secret> | null",
  "ssh_username": "<username> | null",
  "ssh_password": "<plaintext> | '' | null",
  "group_ids": [<int>, ...] | null
}

Semántica:

Respuesta (200 OK):

{
  "success": true,
  "id": <profile_id>
}

Errores:

Lógica de actualización:

  1. Campos SNMP planos (snmp_community, snmp_version, snmp_v3_*): se asignan directamente.
  2. Flag supports_snmp: se activa si hay snmp_community.
  3. SSH password:
    • Si texto no vacío: encripta y almacena en ssh_password_encrypted.
    • Si cadena vacía: borra ssh_password_encrypted = "".
    • Si omitido: no toca.
  4. Flag supports_ssh: se activa si ssh_username y ssh_password_encrypted están ambos presentes.
  5. Grupos:
    • Filtra group_ids contra grupos válidos de la org.
    • Ejecuta profile.groups.set(valid_group_ids).

Log de auditoría: Registra NETWORK.auto_provision.profile_config con la IP del perfil.

Schema Ninja

Archivo: network/api/assign.py

Clase: DeviceProfileConfigIn

class DeviceProfileConfigIn(Schema):
    """Edición de credenciales + grupos de un DeviceProfile. Solo se aplican los
    campos presentes (``exclude_unset``). NO incluye IP ni nombre a propósito."""

    snmp_community: str | None = None
    snmp_version: str | None = None
    snmp_v3_username: str | None = None
    snmp_v3_auth_protocol: str | None = None
    snmp_v3_auth_key: str | None = None
    snmp_v3_priv_protocol: str | None = None
    snmp_v3_priv_key: str | None = None
    ssh_username: str | None = None
    ssh_password: str | None = None  # texto plano de entrada → se cifra; "" = borrar
    group_ids: list[int] | None = None  # None = no tocar; [] = quitar de todos

Tuple auxiliar: _SNMP_PLAIN_FIELDS

_SNMP_PLAIN_FIELDS = (
    "snmp_community",
    "snmp_version",
    "snmp_v3_username",
    "snmp_v3_auth_protocol",
    "snmp_v3_auth_key",
    "snmp_v3_priv_protocol",
    "snmp_v3_priv_key",
)

Ubicación en código

Archivo: network/api/assign.py (líneas ~97–155) Router: @router (Ninja APIRouter para /api/network/) Tags: ["Auto-Provision"]

Funciones:

Dependencias

Importaciones:

Modelos tocados:

Flujo típico (desde modal)

  1. Modal carga: GET /api/network/auto-provision/profiles/{profile_id}/config
    • Retorna config actual con flags has_* en lugar de secretos.
    • Frontend renderiza formulario.
  2. Usuario edita y clica “Save”.
  3. Modal ejecuta PUT /api/network/auto-provision/profiles/{profile_id}/config con delta de cambios.
  4. Backend aplica cambios con exclude_unset=True (solo campos presentes).
  5. Si éxito: modal cierra, lista de dispositivos se recarga.

Notas de seguridad

Casos de prueba

Archivo de tests: tests/api/test_network_profile_config.py

Véase también

Subir