DeviceProfile · Modelo network
Propósito
DeviceProfile es la fuente de verdad sobre cualquier dispositivo de red descubierto por la Auto-Provision Tool. Almacena identidad (IP, hostname, vendor, modelo, serial), capacidades (SNMP/SSH/NETCONF), volcado ifTable SNMP, vecinos LLDP/CDP, deep discovery con MIBs vendor-específicas y confidence_score (0-100). A partir de este registro se auto-configuran Observatory (MonitoringTarget con ifIndex correcto), Rack Editor (sugerencia Stencil) y gestión de red (credenciales SSH).
Contrato
Campos principales:
| Campo | Tipo | Descripción |
|---|---|---|
organization | FK(core.Organization) | Tenant dueño |
ip_address | GenericIPAddressField | IP del dispositivo (PK lógico) |
pending_ip_address | GenericIPAddressField (null) | B-27 (25-09-2026): IP nueva detectada por un re-escaneo, pendiente de que un usuario la confirme o la descarte — ver [[feature—network—readdress-ip]] |
dismissed_ip_address | GenericIPAddressField (null) | B-27: IP que un usuario ya descartó para esta ficha; no se vuelve a proponer |
hostname / fqdn | CharField | Nombre resuelto |
vendor / model | CharField | Fabricante y modelo inferidos |
serial_number / mac_address | CharField | Identidad hardware |
os_type / os_version / firmware_version | CharField | Software |
device_type | CharField(choices) | router/switch/firewall/access_point/… |
capabilities | ArrayField | routing, switching, vpn… |
supports_snmp/ssh/telnet/netconf/restconf | BooleanField | Protocolos confirmados |
snmp_version / snmp_community | CharField | Credenciales SNMP v2c |
snmp_v3_* | CharField | Credenciales SNMPv3 |
snmp_sys_descr / snmp_sys_object_id / snmp_uptime | — | OIDs base |
interfaces | JSONField | ifTable completa keyed por ifIndex |
cpu_count / memory_total_mb / chassis_type | — | Hardware básico |
deep_snmp_data | JSONField | Deep discovery por categoría |
mib_modules_loaded | ArrayField | MIBs usados exitosamente |
lldp_neighbors / cdp_neighbors | JSONField | Vecinos topológicos |
suggested_stencil_id / stencil_confidence | Int | Match fuzzy Stencil |
discovery_method | CharField(choices) | snmp/ssh/snmp+ssh/manual |
confidence_score | IntegerField(0-100) | base 10 + identidad/SNMP/interfaces/hardware/método/plantilla/vecinos (fórmula completa en scoring.py::calculate_confidence); identidad verificada por sysObjectID: +10 si trae fabricante y modelo, +5 si solo uno de los dos o hay plantilla ≥70 (s314, v1.132.0) |
linked_monitoring_target | FK(monitoring.MonitoringTarget) | Auto-creado |
linked_device | FK(racks.Device) | Device vinculado |
groups | M2M(racks.RackGroup) | Grupos |
raw_snmp_data / raw_ssh_data | JSONField | Dumps crudos para debug |
Métodos y propiedades:
get_interface_by_description(description).get_interface_by_index(if_index).get_uplink_interfaces(min_speed_bps=1Gbps)— filtra alta velocidad para Observatory.get_operational_interfaces()—ifOperStatus == 1.interface_count,has_neighbors,neighbor_count(properties).is_high_confidence—confidence_score >= 80.is_linked_to_observatory,is_linked_to_rack_editor(properties).update_last_verified()—timezone.now()conupdate_fields.
Meta:
- Tabla:
device_profiles. unique_together:[organization, ip_address].ordering:-confidence_score, -discovered_at.- Índices:
vendor+model,confidence_score,discovered_at,org+device_type,org+supports_snmp.
Dependencias entrantes
| Módulo | Archivo | Uso |
|---|---|---|
DeviceDiscoveryService | network/services/device_discovery/service.py | provision_device/bulk_provision_subnet |
ProvisionStagesMixin | network/services/device_discovery/provision_stages.py | _persist_profile con update_or_create; antes de apply_manual_lock llama a scoring.py::carry_over_knowledge, que rellena con la ficha anterior los campos que esta pasada trae vacíos (s314) |
AutoConfigService | network/services/auto_config.py | Crea MonitoringTarget, sugiere Stencil |
network/api/discovery.py | API | POST /auto-provision/discover; expone DeviceProfileOut |
network/api/profiles.py | API | CRUD + re-scan ifTable + propagate ports + pending-ip/apply y /dismiss (B-27) |
network/services/readdress.py | Service | change_profile_ip, propose_ip_change, clear_stale_ip_change, dismiss_pending_ip_change (B-27) |
network/services/device_discovery/rescan_hooks.py | Service | readdress_profile_by_mac — propone el cambio pendiente cuando el re-escaneo ve la MAC en otra IP (B-27) |
racks/services/racks.py | Service | Auto-link a Device, inyecta puertos desde ifTable |
monitoring/views.py | Views | bulk_update de linked_monitoring_target |
monitoring/api/wireless.py / ups.py | APIs | Listan y vinculan por device_type |
monitoring/services/group_service.py | Grupos | Consulta por grupo y device_type |
terminal/consumers.py | Sentinel | Resuelve OIDs vía DeviceProfile → VendorProfile |
PortConnection | network/models.py | OneToOne FK port_connection |
signage/models.py | Signage | FK directa desde modelos |
core/services/backup_service.py | Backup | Serializa en exports |
Dependencias salientes
core.Organization— FK CASCADE.monitoring.MonitoringTarget— link auto-creado (SET_NULL).racks.Device— link al Device del Rack Editor (SET_NULL).racks.RackGroup— M2M wireless/UPS/signage groups.network.VendorProfile— consultado por servicios externos; no FK directa.
Ejemplos
- Discovery mínimo: solo
ip_address+organization;confidence_score = 10(ping). - SNMP completo:
snmp_sys_descrpoblado,interfacescon ifTable,confidence_score >= 60. - Full con SSH:
discovery_method = "snmp+ssh",serial_numberyos_versionenriquecidos,confidence_score >= 80. - Post auto-config:
linked_monitoring_targetapunta a MT consnmp_interface_index;linked_deviceapunta al Device con puertos inyectados desdeinterfaces. - Cambio de IP pendiente:
pending_ip_addresspoblada tras un re-escaneo que vio la MAC en otra IP; la ficha sigue sirviendo por suip_addressde siempre hasta que un usuario confirma o descarta (B-27).
Notas operativas
- Backfill de
firmware_version(migraciónnetwork/0065_backfill_firmware_from_deep_snmp, v1.126.0 · 2026-09-06, task #281 pt.3): el escritor determinal/api/sentinel_ingest.pysolo rellenafirmware_versioncuando llega una foto NUEVA de deep discovery — las fichas cuya foto se tomó antes de ese arreglo se quedaban con el campo vacío aunque el dato ya estuviera endeep_snmp_data. La migración es idempotente (solo toca fichas confirmware_versionvacío y foto con valor; lo escrito a mano no se pisa) y usa una copia local del extractor, con un test de paridad contrasentinel_ingest.extract_firmware(tests/network/test_ronda_0906_tanda5.py) para no depender del código vivo. En PROD recuperó 123 de 129 fichas con foto y sin firmware (medido 30-08-2026) — visible en el inventario de puntos de acceso, su detalle, el informe y el CSV. - La nota de confianza sobrevive a una pasada floja (
network/services/device_discovery/scoring.py::carry_over_knowledge, llamado enprovision_stages.py::_persist_profileantes deapply_manual_lock, v1.132.0 · 2026-09-08, medido en el escaneo del CCIB, s314): antes, una pasada que no hablaba SNMP con un equipo ya conocido pisaba hostname/modelo/serie/OS/sysDescr/sysObjectID/CPU/memoria con huecos vacíos, apagabasupports_snmp/supports_ssh, devolvíadevice_typea “other” y recalculaba la nota solo con lo de esa pasada — 47 puntos de acceso Cambium cayeron a 30 (ficha completa: 45) y un switch Cisco a 45 (ficha: 60). Ahora un campo vacío de esta pasada se rellena con el valor anterior, los flags no se apagan, y la nota nunca baja de la que ya tenía la ficha; los campos bloqueados a mano los sigue respetandoapply_manual_lockigual que antes. Además la identidad confirmada porsysObjectIDya no exige plantilla de rack para subir de nota (con fabricante y modelo suma +10 en vez de +5) — un punto de acceso, un SAI o un sensor plenamente identificados dejan de tener techo bajo. Y en los switches Cisco,modelguarda ahora el chasis (p.ej.C9300-48P) en vez de “IOS”, que es el nombre del sistema operativo (ssh_stage.py::_cisco_ios_model). - Cambio de IP pendiente de confirmación (
network/0067_deviceprofile_pending_ip.py, 25-09-2026, decisión de Edu que sustituye la de la task #314): un re-escaneo que ve la MAC de esta ficha en otra IP ya no reescribeip_addresssola; la deja enpending_ip_addresshasta que un usuario la aplica o la descarta desde la página Devices. Campo nuevo → viaja en el backup/restore deracks/api/export/{backup,restore}.py(vigilado portests/api/test_backup_scope.py::test_device_profile_serializer_covers_model_fields). Detalle completo del flujo en [[feature—network—readdress-ip]].
Related
entity--network--model--vendorprofile— proporciona communities, OIDs y regex usados en discovery.entity--racks--model--device— destino delinked_device; recibe puertos desde ifTable.concept--network--auto-provision— flujo orquestado porDeviceDiscoveryService.feature--network--readdress-ip— servicio único que escribeip_address, a mano o vía confirmación de un cambio pendiente.
Véase también
- [[entity—network—model—vendorprofile]]
- [[entity—racks—model—device]]
- [[concept—network—auto-provision]]
- [[feature—network—readdress-ip]]