Auto-Provision: botón Refresh por dispositivo
Descripción general
Sesión 114 (2026-06-08) — Parte 4a de Auto-Provision
En el listado de resultados del escaneo Auto-Provision, cada dispositivo descubierto dispone ahora de un botón Refresh que re-ejecuta el discovery completo de ese dispositivo concreto sin necesidad de re-escanear toda la subred. El refresh reutiliza automáticamente las credenciales guardadas (SNMP + SSH cifradas) en el DeviceProfile.
Motivación
- Eficiencia: cuando un equipo cambia de configuración minor (interfaces nuevas, datos SNMP actualizados), evita re-ejecutar el nmap+discovery de toda la subred.
- Seguridad: las credenciales ya descubiertas y guardadas se reutilizan sin volver a pedirlas al usuario.
- UX: botón simple en el modal de resultados — click y el perfil se actualiza en vivo.
Características
Endpoint: POST /auto-provision/profiles/{id}/rediscover
-
Autenticación: requiere permiso
network.edit+ org actual. -
Entrada: ID del
DeviceProfile(por URL). -
Proceso:
- Carga el
DeviceProfiledel dispositivo. - Extrae sus credenciales guardadas (
snmp_community,ssh_username,ssh_passwordcifrada, SNMP v3 si aplica). - Invoca
DeviceDiscoveryService.provision_device()con esas credenciales. - Actualiza el profile in-place (
update_or_createpor org + IP). - Retorna el
DeviceProfileOutactualizado.
- Carga el
-
Respuesta:
200: DeviceProfileOut actualizado.400: error en re-discovery (conexión fallida, timeout, etc.).404: profile no encontrado o acceso denegado (cross-org).
UI: botón “Refresh” en results.js
- Ubicación: cada fila de la tabla de resultados (columna de acciones).
- Elemento:
<button class="btn btn-neutral btn-sm">Refresh</button>(Regla 7 — texto, no icon). - Acción: invoca
AutoProvision.refreshProfile(profileId)(método endeep_discovery.js). - Comportamiento tras click:
- Muestra toast “Refreshing device…”
- POST al endpoint rediscover.
- Actualiza la fila en vivo (
this.discoveredProfiles[idx] = updated). - Renderiza la tabla.
- Toast de éxito/error.
Método JS: AutoProvision.refreshProfile()
Ubicado en static/js/network/auto_provision/deep_discovery.js. Orquesta el refresh:
async refreshProfile(profileId) {
showToast('Refreshing device — re-running discovery with saved credentials…', 'info');
try {
const updated = await ApiService.post(`/api/network/auto_provision/profiles/${profileId}/rediscover`);
if (updated && updated.error) {
showToast(updated.error, 'error');
return;
}
const idx = this.discoveredProfiles.findIndex(p => p.id === profileId);
if (idx >= 0 && updated && updated.id) {
this.discoveredProfiles[idx] = updated;
this.renderResults();
}
showToast('Device refreshed.', 'success');
} catch (error) {
showToast(`Refresh failed: ${error.message || error}`, 'error');
}
}
Entidades tocadas
- Modelo:
DeviceProfile(network.models) — se actualiza in-place víaprovision_device(). - Servicio:
DeviceDiscoveryService(network.services.device_discovery.service) — orquesta ping, SNMP, SSH, MIBs. - Endpoint:
rediscover_profile(network.api.discovery) — nuevo handler async. - JS:
deep_discovery.js(referencia de método),results.js(UI del botón).
Sinergia con sesión 114
Esta feature depende directamente de la herencia de credenciales SSH (Sesión 114, Terminal) que ahora persiste las contraseñas SSH en DeviceProfile.ssh_password_encrypted. Sin eso, el refresh tendría que pedir credenciales de nuevo.
Notas de implementación
- Async endpoint: usa
sync_to_asyncpara operaciones de BD. - Validación de org:
DeviceProfile.objects.filter(id=..., organization=org)previene leaks cross-org. - Logging: registra la acción vía
log_action(request, "NETWORK", "auto_provision.rediscover", ip)para auditoría. - Manejo de errores: traceback completo en logs si falla el discovery.
Pendiente (Parte 4b)
La Parte 4 completa incluye también la carga/recuperación de búsquedas guardadas desde la UI. Ya se persisten en localStorage vía sessions.js, pero falta la UI para listarlas y recargarlas.
Véase también
- [[entity—network—endpoint—rediscover-profile]]
- [[entity—network—model—device-profile]]
- [[entity—network—service—device-discovery-service]]
- [[concept—network—multi-tenancy]]
- [[concept—network—credential-storage]]
- [[concept—network—snmp]]
- [[concept—network—async-patterns]]
- [[decision—20260603—persist-ssh-credentials]]