Files
driver-standard/template/napalm_example/parsers/__init__.py
T
christianmanivong db6b2e4ea7
CI / test (3.11) (push) Successful in 34s
CI / test (3.12) (push) Successful in 30s
CI / test (3.13) (push) Successful in 37s
feat: standards, shared CI and release tooling for NAPALM drivers
STANDARDS.md binds every repository in the NAPALM org: one default branch,
Conventional Commits, the device-types contract, test-driven development,
clean-code limits, a quality ratchet for existing code, packaging rules and
releases by tag to PyPI.

napalm-standard holds what a tool can check: the conformance check (with
release rules on a tag), the quality ratchet (ported from netOrk's
quality_ratchet.py), and the Gitea release from the CHANGELOG section.
.gitea/workflows/driver.yml is the CI every driver calls; template/ is a new
driver's starting point and passes the check as it is.
2026-10-22 19:01:14 +02:00

46 lines
1.6 KiB
Python

"""Pure functions: device output in, typed values out. No I/O here."""
from __future__ import annotations
import re
from typing import TypedDict
#: "Key : value" lines of `show version`.
_FIELD = re.compile(r"^(?P<key>[^:\n]+?)\s*:\s*(?P<value>.*)$", re.MULTILINE)
#: "3 days, 4:05:06" or "4:05:06".
_UPTIME = re.compile(r"^(?:(?P<days>\d+) days?, )?(?P<h>\d+):(?P<m>\d\d):(?P<s>\d\d)$")
_SECONDS_PER_DAY = 86400
class VersionDict(TypedDict):
model: str
hostname: str
os_version: str
serial_number: str
uptime: float
def parse_uptime(text: str) -> float:
"""Seconds from an uptime like ``3 days, 4:05:06``."""
match = _UPTIME.match(text.strip())
if not match:
raise ValueError(f"unreadable uptime: {text!r}")
days = int(match.group("days") or 0)
hours, minutes, seconds = (int(match.group(k)) for k in ("h", "m", "s"))
return float(days * _SECONDS_PER_DAY + hours * 3600 + minutes * 60 + seconds)
def parse_version(text: str) -> VersionDict:
"""Facts from ``show version``; a field the device did not print is an error."""
fields = {m.group("key").strip(): m.group("value").strip() for m in _FIELD.finditer(text)}
try:
return {
"model": text.splitlines()[0].removesuffix(" Switch").strip(),
"hostname": fields["Hostname"],
"os_version": fields["Firmware"],
"serial_number": fields["Serial number"],
"uptime": parse_uptime(fields["Uptime"]),
}
except KeyError as exc:
raise ValueError(f"show version lacks {exc.args[0]}") from exc