feat: SnmpHealthProfile, the OIDs a driver declares; deprecate HealthMetricsMixin (4.11.0)
CI / test (3.10) (push) Successful in 35s
CI / test (3.11) (push) Successful in 28s
CI / test (3.12) (push) Successful in 29s
CI / test (3.13) (push) Successful in 27s
CI / test (3.10) (pull_request) Successful in 31s
CI / test (3.11) (pull_request) Successful in 31s
CI / test (3.12) (pull_request) Successful in 35s
CI / test (3.13) (pull_request) Successful in 35s

Drivers no longer collect over SNMP (docs/STRUCTURE.md). A driver whose
device publishes its health values under OIDs of its own declares them
as SNMP_HEALTH_PROFILE: per value either scalars asked in order or a
table folded by first, average or max, optionally with a pattern for
text answers; memory as total with used or free, or a percentage, in
KiB or bytes; and how to read the interfaces. The application polls
and computes.

HealthMetricsMixin.get_health_metrics now warns that it is deprecated;
it goes in 5.0.

Closes #32
This commit is contained in:
christianmanivong committed 2026-10-16 12:00:06 +02:00
1 parent 2739f10ecd
commit 64cc20ba00
6 files changed
+143 -2

No files matched your search

+8
View File
@@ -103,6 +103,10 @@ from napalm_device_types.models import (
ManagementProtocolsDict,
PowerAction,
PowerStateDict,
SnmpHealthProfile,
SnmpInterfacesSpec,
SnmpMemorySpec,
SnmpValueSpec,
)
from napalm_device_types.nat_vpn import NatVpnMixin
from napalm_device_types.packages import PackageManagementMixin
@@ -148,6 +152,10 @@ from napalm_device_types.storage import StorageDriver
from napalm_device_types.switch import SwitchDriver
__all__ = [
"SnmpHealthProfile",
"SnmpInterfacesSpec",
"SnmpMemorySpec",
"SnmpValueSpec",
"AccessPointDriver",
"ByteStream",
"CommandChannelMixin",
+17 -1
View File
@@ -1,6 +1,11 @@
# -*- coding: utf-8 -*-
"""SNMP health collection, shared by every device type that speaks UCD-MIB.
**Deprecated** (docs/STRUCTURE.md): drivers do not collect over SNMP. The
application polls; a driver whose device publishes values under its own OIDs
declares them as ``SNMP_HEALTH_PROFILE`` (:class:`~napalm_device_types.models.SnmpHealthProfile`).
This mixin goes in 5.0.
The collection itself is generic: CPU, memory, uptime, load and per-interface
counters come from the same standard OIDs on any UCD-MIB/IF-MIB capable device.
Only two details vary by device type, and both are class attributes rather than
@@ -15,6 +20,7 @@ implement ``get_health_metrics`` themselves.
from __future__ import annotations
import re
import warnings
from typing import Any, Awaitable, Callable, ClassVar, Dict, cast
from napalm_device_types._ucd_metrics import IF_SKIP_DEFAULT, collect_ucd_metrics
@@ -39,7 +45,17 @@ class HealthMetricsMixin:
snmp_get: Callable[..., Awaitable[Any]],
snmp_walk: Callable[..., Awaitable[Dict[str, Any]]],
) -> HealthMetricsDict:
"""Collect SNMP health metrics (CPU, memory, uptime, load, interfaces)."""
"""Collect SNMP health metrics (CPU, memory, uptime, load, interfaces).
Deprecated: the application polls; see the module docstring.
"""
warnings.warn(
"HealthMetricsMixin.get_health_metrics is deprecated and goes in 5.0: "
"the application polls over SNMP; a driver declares only its OIDs, "
"as SNMP_HEALTH_PROFILE",
DeprecationWarning,
stacklevel=2,
)
# collect_ucd_metrics is untyped shared plumbing; the shape it returns is
# the contract HealthMetricsDict describes.
return cast(
+47
View File
@@ -951,6 +951,53 @@ class HealthMetricsDict(TypedDict):
interfaces: NotRequired[Dict[str, HealthMetricsIfaceDict]]
class SnmpValueSpec(TypedDict, total=False):
"""Where an SNMP agent publishes one value, inside a ``SnmpHealthProfile``.
Either ``oids``, scalars asked in order (the first non-empty answer wins), or
``table``, a column walked and folded to one value by ``fold``. ``pattern`` is a
regular expression whose first group is the number, for an agent that answers
with text.
"""
oids: List[str]
table: str
fold: Literal["first", "average", "max"]
pattern: str
class SnmpMemorySpec(TypedDict, total=False):
"""Memory: ``total`` with ``used`` or ``free``, or ``percent`` alone."""
total: SnmpValueSpec
used: SnmpValueSpec
free: SnmpValueSpec
percent: SnmpValueSpec
unit: Literal["KiB", "bytes"] # of total, used and free; KiB, as UCD-MIB counts, by default
class SnmpInterfacesSpec(TypedDict, total=False):
"""How the IF-MIB counters of a device are to be read."""
skip: str # a pattern of interface names whose counters are noise, not signal
tx_errors_are_drops: bool # the device counts dropped packets as TX errors (OPNsense)
class SnmpHealthProfile(TypedDict, total=False):
"""Where a device's SNMP agent publishes its health values.
A driver declares it as ``SNMP_HEALTH_PROFILE`` when its device does not answer
the standard UCD-MIB and IF-MIB; the application polls and computes. What a
profile does not name is read the standard way. Uptime is in TimeTicks, CPU in
percent busy.
"""
uptime: SnmpValueSpec
cpu: SnmpValueSpec
memory: SnmpMemorySpec
interfaces: SnmpInterfacesSpec
class NICConfigDict(TypedDict):
"""Network interface configuration for VM provisioning."""