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 <noreply@anthropic.com>
This commit is contained in:
Christian Manivong
2026-06-22 23:27:15 +02:00
co-authored by Claude Sonnet 4.6
parent d2915f5829
commit da5920a9bc
2 changed files with 25 additions and 13 deletions
+21 -11
View File
@@ -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
# ---------------------------------------------------------------------------
+4 -2
View File
@@ -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)