chore: adopt the NAPALM driver standard #2

Merged
christianmanivong merged 4 commits from chore/driver-standard into main 2026-10-23 09:28:20 +00:00
Owner

Summary

napalm-amt adopts the NAPALM driver standard (https://git.netork.io/NAPALM/driver-standard).
Epic: NAPALM/driver-standard#2.

Changes

  • style: the standard's ruff rule set (E, F, I, UP, B, line length 100, E501 off under tests/); the code was already formatted and clean under it.
  • fix: WS-Management answers are parsed with defusedxml (new dependency defusedxml>=0.7) with DTDs forbidden. The <!DOCTYPE byte check it replaces missed a DTD in a UTF-16 answer, which expat reads too; on plain HTTP (16992) anyone in the path can send one. New tests: a DTD in UTF-8 and UTF-16 is refused, an answer that is no XML raises (B314, B405). xml.sax.saxutils only escapes request envelopes (nosec B406). python -m napalm_amt.record keeps fetching the unauthenticated landing page without certificate checks: no credentials go out, it records what discovery sees (nosec B501). The driver still verifies by default (verify_ssl=True).
  • chore: CI in .gitea/workflows/ci.yml calling the shared workflow (the repo had none); setuptools>=77, SPDX license string, napalm-device-types>=4.21.1 from PyPI, Issues/Changelog links; test extra replaced by the standard dev extra plus responses; strict mypy with the untyped imports named per module, napalm_amt.driver exempt (5 override errors: getters return plain dicts where the role declares TypedDicts); coverage floor 95 %; tests/quality_baseline.json (get_event_log complexity 11); CHANGELOG in Keep a Changelog form. LICENSE, NOTICE and py.typed stay as they were.

Related Issue

Closes #1

Testing

Locally: 160 tests, coverage 95.87 %, ruff, mypy, bandit clean; napalm-standard check and ratchet clean; build + twine check --strict pass. The tests also pass at the lowest declared versions (fixtures only).

## Summary napalm-amt adopts the NAPALM driver standard (https://git.netork.io/NAPALM/driver-standard). Epic: NAPALM/driver-standard#2. ## Changes - **style**: the standard's ruff rule set (E, F, I, UP, B, line length 100, E501 off under `tests/`); the code was already formatted and clean under it. - **fix**: WS-Management answers are parsed with defusedxml (new dependency `defusedxml>=0.7`) with DTDs forbidden. The `<!DOCTYPE` byte check it replaces missed a DTD in a UTF-16 answer, which expat reads too; on plain HTTP (16992) anyone in the path can send one. New tests: a DTD in UTF-8 and UTF-16 is refused, an answer that is no XML raises (B314, B405). `xml.sax.saxutils` only escapes request envelopes (nosec B406). `python -m napalm_amt.record` keeps fetching the unauthenticated landing page without certificate checks: no credentials go out, it records what discovery sees (nosec B501). The driver still verifies by default (`verify_ssl=True`). - **chore**: CI in `.gitea/workflows/ci.yml` calling the shared workflow (the repo had none); setuptools>=77, SPDX license string, `napalm-device-types>=4.21.1` from PyPI, Issues/Changelog links; `test` extra replaced by the standard `dev` extra plus `responses`; strict mypy with the untyped imports named per module, `napalm_amt.driver` exempt (5 override errors: getters return plain dicts where the role declares TypedDicts); coverage floor 95 %; `tests/quality_baseline.json` (get_event_log complexity 11); CHANGELOG in Keep a Changelog form. LICENSE, NOTICE and `py.typed` stay as they were. ## Related Issue Closes #1 ## Testing Locally: 160 tests, coverage 95.87 %, ruff, mypy, bandit clean; `napalm-standard check` and `ratchet` clean; build + `twine check --strict` pass. The tests also pass at the lowest declared versions (fixtures only).
christianmanivong added 3 commits 2026-10-23 06:37:58 +00:00
Mechanical: the rule set every NAPALM driver uses (E, F, I, UP, B at line
length 100, Python 3.10), with E501 off under tests/. The code was already
formatted and clean under it; what ruff cannot fix comes in the next commit.
- WS-Management answers are parsed with defusedxml (new dependency,
  defusedxml>=0.7) with DTDs forbidden. The check for "<!DOCTYPE" in the raw
  bytes it replaces missed a DTD in a UTF-16 answer, which expat reads too;
  on plain HTTP (16992) anyone in the path can send one. An answer with a
  DTD in any encoding is now refused as no WS-Management answer, as a UTF-8
  one already was (B314, B405).
- xml.sax.saxutils only escapes the request envelopes, nothing parses with
  SAX (nosec B406).
- python -m napalm_amt.record fetches the landing page without certificate
  checks, as before: it sends no credentials and records what discovery
  sees, and AMT's certificate is self-signed unless one was provisioned
  (nosec B501). The driver itself still verifies by default (verify_ssl).
chore: adopt the NAPALM driver standard
driver / standard (pull_request) Successful in 13s
driver / lint (pull_request) Successful in 12s
driver / types (pull_request) Successful in 43s
driver / test (3.10) (pull_request) Successful in 46s
driver / test (3.11) (pull_request) Successful in 48s
driver / test (3.12) (pull_request) Successful in 43s
driver / test (3.13) (pull_request) Successful in 39s
driver / lowest (pull_request) Successful in 23s
driver / security (pull_request) Successful in 46s
driver / build (pull_request) Successful in 22s
CI / driver (pull_request) Successful in 5m37s
driver / publish (pull_request) Skipped
c9a7ee4378
- CI arrives in .gitea/workflows/ci.yml and calls the shared driver
  workflow of NAPALM/driver-standard; the repo had none before.
- setuptools>=77 and the SPDX license string PEP 639 wants, without the
  License classifier; napalm-device-types>=4.21.1 from PyPI; Issues and
  Changelog links on git.netork.io. LICENSE, NOTICE and py.typed were
  already there and stay.
- The test extra becomes the dev extra of the standard, plus responses,
  which the tests mock AMT with.
- mypy strict with the untyped imports (napalm, requests, defusedxml)
  named instead of ignored globally; napalm_amt.driver is exempt for now
  (5 errors: getters return dicts where the role declares TypedDicts),
  recorded in tests/quality_baseline.json with get_event_log's
  complexity of 11.
- Coverage floor 95 % (measured 95.87 %).
- CHANGELOG.md in Keep a Changelog form; the README's development steps
  install from PyPI.
christianmanivong added 1 commit 2026-10-23 08:29:00 +00:00
chore(release): 0.2.0
driver / standard (pull_request) Successful in 18s
driver / lint (pull_request) Successful in 16s
driver / types (pull_request) Successful in 55s
driver / test (3.10) (pull_request) Successful in 1m8s
driver / test (3.11) (pull_request) Successful in 1m7s
driver / test (3.12) (pull_request) Successful in 59s
driver / test (3.13) (pull_request) Successful in 49s
driver / lowest (pull_request) Successful in 23s
driver / security (pull_request) Successful in 47s
driver / build (pull_request) Successful in 23s
CI / driver (pull_request) Successful in 7m5s
driver / publish (pull_request) Skipped
0aec58fe06
christianmanivong merged commit ffa561289b into main 2026-10-23 09:28:20 +00:00
christianmanivong deleted branch chore/driver-standard 2026-10-23 09:28:20 +00:00
Sign in to join this conversation.