From bfbeb1925547832bcfcec20019936be3b2d1487d Mon Sep 17 00:00:00 2001 From: Christian Manivong Date: Tue, 13 Oct 2026 10:19:56 +0200 Subject: [PATCH] fix: group alternative fingerprint rules (0.1.2) One Redfish answer (the service root or the error a service refuses it with) and one landing page (Supermicro/ATEN, iDRAC or iLO) can match, never all of them. Grouped, the driver's maximum in netOrk's discovery is 21 instead of 41, and a Supermicro landing page alone (6 of 21) outranks the "linux" its BMC reports over SNMP (5 of 18). Requires napalm-device-types 4.8 for FingerprintRule.group. --- CHANGELOG.md | 8 ++++++++ napalm_redfish/__init__.py | 2 +- napalm_redfish/driver.py | 14 ++++++++------ pyproject.toml | 4 ++-- tests/test_discovery.py | 16 ++++++++++++++++ 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8484c87..97963bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.1.2] - 2026-10-13 + +### Fixed +- The fingerprint rules are grouped into alternatives (one Redfish answer, one landing + page), so discovery's maximum for this driver is 21, not 41. With every alternative + summed, a Supermicro landing page (6 of 41) lost to a bare "linux" in the BMC's own + SNMP sysDescr (5 of 18). Requires napalm-device-types 4.8. + ## [0.1.1] - 2026-10-13 ### Fixed diff --git a/napalm_redfish/__init__.py b/napalm_redfish/__init__.py index ac1dca5..2f1a3fe 100644 --- a/napalm_redfish/__init__.py +++ b/napalm_redfish/__init__.py @@ -2,5 +2,5 @@ from napalm_redfish.driver import RedfishDriver -__version__ = "0.1.1" +__version__ = "0.1.2" __all__ = ["RedfishDriver"] diff --git a/napalm_redfish/driver.py b/napalm_redfish/driver.py index 3d15366..4df9ad2 100644 --- a/napalm_redfish/driver.py +++ b/napalm_redfish/driver.py @@ -112,16 +112,18 @@ class RedfishDriver(ManagementControllerDriver): #: Every Redfish service answers ``GET /redfish/v1/`` without credentials. The port #: itself is worth nothing: every switch with a web UI answers on 443. PORT_SPECS = [PortSpec("https", 443, ("/redfish/v1/",), weight=0.0)] + #: Rules in one group are alternatives and count once towards the maximum + #: (napalm-device-types' ``rules_max_weight``). HTTP_FINGERPRINT = [ - # The service root, and the error body a service refuses it with (an unlicensed + # The service root, or the error body a service refuses it with (an unlicensed # Supermicro X10 answers 403 with a Redfish error). - FingerprintRule("redfishversion", 10.0), + FingerprintRule("redfishversion", 10.0, group="redfish_answer"), + FingerprintRule("@message.extendedinfo", 8.0, group="redfish_answer"), FingerprintRule("#serviceroot.", 5.0), - FingerprintRule("@message.extendedinfo", 8.0), # Landing pages of the BMC web UIs: Supermicro X9-X11 (ATEN firmware), iDRAC, iLO. - FingerprintRule("aten international", 6.0), - FingerprintRule("idrac", 6.0), - FingerprintRule("integrated lights-out", 6.0), + FingerprintRule("aten international", 6.0, group="landing_page"), + FingerprintRule("idrac", 6.0, group="landing_page"), + FingerprintRule("integrated lights-out", 6.0, group="landing_page"), ] #: A BMC restart takes a few minutes before Redfish answers again. REBOOT_SETTLE_SECONDS = 180 diff --git a/pyproject.toml b/pyproject.toml index 5af4242..2f7dd38 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "napalm-redfish" -version = "0.1.1" +version = "0.1.2" description = "NAPALM driver for server baseboard management controllers over DMTF Redfish" readme = "README.md" license = { file = "LICENSE" } @@ -12,7 +12,7 @@ requires-python = ">=3.10" dependencies = [ "napalm>=5.0", # Not on PyPI: install from git before this package (see README). - "napalm-device-types>=4.7", + "napalm-device-types>=4.8", "redfish>=3.2", ] classifiers = [ diff --git a/tests/test_discovery.py b/tests/test_discovery.py index e039639..62902bb 100644 --- a/tests/test_discovery.py +++ b/tests/test_discovery.py @@ -45,3 +45,19 @@ def test_idrac_and_ilo_landing_pages_are_recognised(): def test_a_switch_page_scores_nothing(): page = 'Loading...Web Switch' assert _score(page) == 0.0 + + +def test_alternatives_count_once_towards_the_maximum(): + # One Redfish answer (service root or error), the service root's type marker, and one + # landing page: 10 + 5 + 6. Summing every alternative (41) let a bare "linux" in the + # BMC's SNMP sysDescr (5 of 18) beat the Supermicro landing page (6 of 41). + from napalm_device_types import rules_max_weight + + assert rules_max_weight(RedfishDriver.HTTP_FINGERPRINT) == 21.0 + + +def test_supermicro_landing_page_alone_outranks_a_linux_sysdescr(): + from napalm_device_types import rules_max_weight + + page = _score((X10 / "landing_page.html").read_text()) + assert page / rules_max_weight(RedfishDriver.HTTP_FINGERPRINT) > 5.0 / 18.0