Descripción
Módulo monitoring/services/snmp_service.py que ejecuta queries SNMP (get, walk, interfaces). Implementa el protocolo SNMPv2c y SNMPv3 usando pysnmp.
En sesión 107 se mejoró el logging para debugging sin exponer credenciales.
Cambios sesión 107
Logging de excepciones SNMP
Antes: Los métodos get_single, walk, get_interface_traffic y test_connection tragaban excepciones sin logging:
except Exception:
return None # or pass
Ahora: Se registran en DEBUG:
except Exception as e:
logger.debug("SNMP get failed for %s oid=%s: %s", self.host, oid, e)
return None
Permite debugging sin impacto en producción (logs a DEBUG level).
test_connection() no expone str(exc)
Antes: devolvía {"success": False, "error": str(e)}
Ahora: devolvía {"success": False, "error": "SNMP connection failed"} (genérico) + log warning interno:
except Exception as e:
logger.warning("SNMP test_connection failed for %s: %s", self.host, e)
return {"success": False, "error": "SNMP connection failed"}
Credenciales SNMP v3 en logs
Antes (network/services/device_discovery/snmp_auth.py):
logger.debug(f"[SNMP] v3 auth: user={username}, auth={auth_protocol}, priv={priv_protocol}")
Ahora: No incluye username:
logger.debug(f"[SNMP] v3 auth configured: auth={auth_protocol or 'none'}, priv={priv_protocol or 'none'}")
Evita registrar credenciales en logs (sensitive data).
Métodos principales
__init__(host: str, version: str = "2c", community: str | None = None, **v3_kwargs)
Constructor. Almacena parámetros SNMP (host, versión, credenciales).
async get_single(oid: str) → str | None
Obtiene un valor SNMP individual (OID).
Parámetros:
oid(str): OID (ej.1.3.6.1.2.1.1.1.0para sysDescr)
Retorna: String con el valor, o None si no disponible/error.
Cambio sesión 107: Ahora loga logger.debug(...) en caso de excepción.
async walk(oid: str) → dict[int, str]
Camina un árbol SNMP (múltiples valores bajo un OID base).
Retorna: Dict {index: value_str}.
Cambio sesión 107: Loga excepción en DEBUG.
def get_interfaces() → list[InterfaceStats]
Obtiene todas las interfaces (OIDs estándar: ifIndex, ifName, ifType, ifSpeed, etc.).
Retorna: Lista de InterfaceStats (dataclass).
async get_interface_traffic(interface_index: int) → dict | None
Obtiene octetos in/out de una interfaz específica.
Retorna: {"in_octets": int, "out_octets": int} o None si no disponible.
Cambio sesión 107: Loga excepción en DEBUG.
def test_connection() → dict
Prueba conectividad SNMP (intenta leer sysUpTime, 1.3.6.1.2.1.1.3.0).
Retorna: {"success": True} o {"success": False, "error": "..."}
Cambio sesión 107: No expone str(e) al cliente, loga en WARNING.
def get_system_info() → dict
Lee grupo SNMP system (sysDescr, sysObjectID, sysUpTime, sysContact, sysName, sysLocation).
Dataclass InterfaceStats
@dataclass
class InterfaceStats:
index: int
name: str
type: str # "ethernetCsmacd", "softwareLoopback", etc.
speed: int | None # bits per second
mtu: int | None
admin_status: str # "up", "down", "testing"
oper_status: str # "up", "down", "testing"
in_octets: int | None
out_octets: int | None
def to_dict(self) -> dict:
"""Convierte a dict (para API)."""
OIDs conocidos
OIDS = {
"sysDescr": "1.3.6.1.2.1.1.1.0",
"sysUpTime": "1.3.6.1.2.1.1.3.0",
# ... más en el código
"ifInOctets": "1.3.6.1.2.1.2.2.1.10", # HC: 1.3.6.1.2.1.31.1.1.1.6
"ifOutOctets": "1.3.6.1.2.1.2.2.1.16", # HC: 1.3.6.1.2.1.31.1.1.1.10
}
Autenticación SNMP
Se configura vía monitoring.models.MonitoringTarget.config:
{
"snmp_version": "2c",
"snmp_community": "public"
}
o para v3:
{
"snmp_version": "3",
"snmp_username": "user",
"snmp_auth_type": "md5",
"snmp_auth_pass": "pass",
"snmp_priv_type": "des",
"snmp_priv_pass": "privpass"
}
Las credenciales se construyen en network/services/device_discovery/snmp_auth.py (no las logueamos en v3).
Testing
Cubierto por tests de autorización (sesión 107) en tests/api/test_monitoring.py. Tests funcionales más profundos dependen de fixtures SNMP reales o mocks.
Véase también
- [[entity—monitoring—api—snmp]]
- [[feature—monitoring—sesion-107-auditoria-suprema-sub-area-2]]
- [[entity—monitoring—models—target]]
Referenciado desde
- Ancho de banda por interfaz SNMP · Agente 2.22.0 cierra A10 y A47 de la auditoría #261
- API SNMP endpoints — test, interfaces, poll con autorización
- Auditoría #261 ciclo 1 — las gráficas de tráfico SNMP vuelven a tener quien las alimente
- Auditoria Suprema · Monitoring SA2 (Protocolos/Probes) + SA3 (CNS/IA)
- Auditoría Suprema 2 · Cola monitoring D: rendimiento de deep-discovery y de Wireless/UPS
- Las gráficas de SAI, vivas de fábrica — walk_first, validación de tipos OID y guardia de frescura (task #255, v1.82.5)
- Selector de interfaz en la gráfica de Bandwidth del Observatory (cierra #262)
- Sesión 107: Auditoría Suprema — monitoring sub-área 2 (protocolos SNMP·ping·HTTP)