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)