From da5920a9bcaf570717b392327b236edb6250af13 Mon Sep 17 00:00:00 2001 From: Christian Manivong Date: Mon, 22 Jun 2026 23:27:15 +0200 Subject: [PATCH] fix: parse_model_from_version handles both HP banner orderings Old switches show: "HP J9298A Switch 2520G-8-PoE" (model after Switch) Newer switches: "HP J9565A 2520G-8-PoE Switch" (model before Switch) New approach: strip vendor prefix + J-code + "Switch" keyword, leaving just the product name. Returns tuple (model, part_number). Co-Authored-By: Claude Sonnet 4.6 --- napalm_procurve/parsers.py | 32 +++++++++++++++++++++----------- napalm_procurve/procurve.py | 6 ++++-- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/napalm_procurve/parsers.py b/napalm_procurve/parsers.py index bacba07..2d88a6c 100644 --- a/napalm_procurve/parsers.py +++ b/napalm_procurve/parsers.py @@ -188,20 +188,30 @@ def parse_version(output: str) -> str: return "" -def parse_model_from_version(output: str) -> str: - """Extract model from ``show version`` first line. +def parse_model_from_version(output: str) -> tuple[str, str]: + """Extract (model, part_number) from ``show version`` first line. - Example: ``HP J9565A 2520G-8-PoE Switch`` → ``2520G-8-PoE`` + Handles both orderings of the HP banner: + ``HP J9565A 2520G-8-PoE Switch`` → ("2520G-8-PoE", "J9565A") + ``HP J9298A Switch 2520G-8-PoE`` → ("2520G-8-PoE", "J9298A") + ``Aruba 2530-8-PoE+ Switch`` → ("2530-8-PoE+", "") """ first = output.strip().splitlines()[0] if output.strip() else "" - m = re.search(r"HP\s+\S+\s+(\S+)\s+Switch", first, re.I) - if m: - return m.group(1) - # Aruba format: "Aruba 2530-8-PoE+ Switch" - m = re.search(r"(?:Aruba|HP)\s+(\d\S+)\s+(?:Switch|)", first, re.I) - if m: - return m.group(1) - return "" + if not first: + return "", "" + + # Extract J-code part number + _PN_RE_V = re.compile(r"\b(J\d{4}[A-Z]{1,2})\b") + pn_match = _PN_RE_V.search(first) + part_number = pn_match.group(1) if pn_match else "" + + # Strip vendor prefix, J-code and "Switch" keyword to get the product name + cleaned = re.sub(r"\b(?:HP|HPE|Aruba)\b", "", first, flags=re.I) + cleaned = _PN_RE_V.sub("", cleaned) + cleaned = re.sub(r"\bSwitch\b", "", cleaned, flags=re.I) + cleaned = re.sub(r"\s{2,}", " ", cleaned).strip(" -()") + + return cleaned, part_number # --------------------------------------------------------------------------- diff --git a/napalm_procurve/procurve.py b/napalm_procurve/procurve.py index 479fcee..4e3a7a8 100644 --- a/napalm_procurve/procurve.py +++ b/napalm_procurve/procurve.py @@ -413,10 +413,12 @@ class ProcurveDriver(ConfigLifecycleMixin, SwitchDriver): ) parsed = parsers.parse_system_info(sysinfo) - # get model from show version if not in system-info + # get model (and part_number) from show version if not in system-info if not parsed["model"]: ver_out = self._send_command("show version") - parsed["model"] = parsers.parse_model_from_version(ver_out) + parsed["model"], ver_pn = parsers.parse_model_from_version(ver_out) + if ver_pn and not parsed.get("part_number"): + parsed["part_number"] = ver_pn if not parsed["os_version"]: parsed["os_version"] = parsers.parse_version(ver_out)