chore: adopt the NAPALM driver standard
driver / standard (pull_request) Successful in 13s
driver / lint (pull_request) Successful in 11s
driver / types (pull_request) Successful in 46s
driver / test (3.10) (pull_request) Successful in 51s
driver / test (3.11) (pull_request) Successful in 55s
driver / test (3.12) (pull_request) Successful in 49s
driver / test (3.13) (pull_request) Successful in 43s
driver / lowest (pull_request) Successful in 26s
driver / security (pull_request) Successful in 49s
driver / build (pull_request) Successful in 22s
CI / driver (pull_request) Successful in 6m5s
driver / publish (pull_request) Skipped

- 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; py.typed; Repository, Issues and Changelog links on
  git.netork.io; napalm-device-types>=4.21.1 from PyPI.
- True floors, found by running the tests at them: redfish>=3.4.1 (older
  releases return no response with max_retry=0) and pyghmi>=1.5.1 (1.5.0
  imports python-dateutil without declaring it).
- The test extra becomes the dev extra of the standard, plus responses,
  which the tests mock the BMC with. pytest puts the repo root on the
  path, so tests.conftest also imports under a bare pytest.
- mypy strict; exempt for now (50 errors, most of them getters returning
  dicts where the role declares TypedDicts): napalm_redfish.bmc, .driver,
  .ipmi, .transport and parsers.common, .environment, .manager, .system.
  They are recorded in tests/quality_baseline.json with seven functions
  over complexity 10.
- Coverage floor 94 % (measured 94.27 %).
- The README's development steps install from PyPI.
This commit is contained in:
Christian Manivong committed 2026-10-23 08:46:19 +02:00
1 parent 01b2a2ae58
commit 8dac2e67dd
7 files changed
+109 -18

No files matched your search

+15
View File
@@ -0,0 +1,15 @@
name: CI
on:
push:
branches: [main]
tags: ["v*"]
pull_request:
jobs:
driver:
uses: NAPALM/driver-standard/.gitea/workflows/driver.yml@main
with:
standard-ref: main
secrets:
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
+3
View File
@@ -5,3 +5,6 @@ build/
dist/
.venv/
.pytest_cache/
.coverage
.mypy_cache/
.ruff_cache/
+11
View File
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Changed
- The driver follows the NAPALM driver standard
(https://git.netork.io/NAPALM/driver-standard): CI on Gitea runs ruff, mypy, the
tests on Python 3.10–3.13 and at the lowest declared versions, bandit, pip-audit and
a build check, and a release tag publishes to PyPI. Python 3.10 stays the floor; the
package now ships `py.typed`, and the license is declared as the SPDX string
`Apache-2.0`. napalm-device-types now comes from PyPI (4.21.1 or later).
- Requires redfish 3.4.1 and pyghmi 1.5.1: older redfish releases return no answer
with `retries=0`, and pyghmi 1.5.0 misses a dependency it imports.
- A failed IPMI logout on close is now logged at debug level.
## [0.5.0] - 2026-10-17
### Added
+4 -5
View File
@@ -78,8 +78,6 @@ These follow the other drivers in the `NAPALM` organisation:
- Parsing lives in pure functions, tested on recorded responses under
`tests/fixtures/<vendor>-<model>-<firmware>/`, with a `COMMANDS.txt` (here: the request
paths) listing what produced each file.
- `napalm-device-types` is not on PyPI: install it from
`git+https://git.netork.io/NAPALM/napalm-device-types.git` before this package.
## Usage
@@ -104,11 +102,12 @@ to basic auth only if the service cannot create sessions), `retries` (1).
## Development
The rules are in [STANDARDS.md](https://git.netork.io/NAPALM/driver-standard/src/branch/main/STANDARDS.md).
```bash
python -m venv .venv && . .venv/bin/activate
pip install git+https://git.netork.io/NAPALM/napalm-device-types.git
pip install -e '.[test]'
pytest
pip install -e '.[dev]'
pytest --cov
```
Fixtures from the DMTF mockups live under `tests/fixtures/dmtf-<mockup>/`, unmodified, with
View File
Whitespace-only changes.
+51 -13
View File
@@ -1,5 +1,5 @@
[build-system]
requires = ["setuptools>=64"]
requires = ["setuptools>=77"]
build-backend = "setuptools.build_meta"
[project]
@@ -7,27 +7,30 @@ name = "napalm-redfish"
version = "0.5.0"
description = "NAPALM driver for server baseboard management controllers over DMTF Redfish"
readme = "README.md"
license = { file = "LICENSE" }
license = "Apache-2.0"
requires-python = ">=3.10"
dependencies = [
"napalm>=5.0",
# Not on PyPI: install from git before this package (see README).
"napalm-device-types>=4.15",
"redfish>=3.2",
"pyghmi>=1.5",
"napalm-device-types>=4.21.1",
# Before 3.4.1, max_retry=0 (retries=0) gets no response back at all.
"redfish>=3.4.1",
# 1.5.0 imports python-dateutil without declaring it.
"pyghmi>=1.5.1",
]
classifiers = [
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3",
"Topic :: System :: Hardware",
"Topic :: System :: Networking",
]
[project.optional-dependencies]
test = [
"pytest>=7",
"responses>=0.23",
]
# responses mocks the BMC's HTTP answers in the tests.
dev = ["pytest>=8", "pytest-cov>=5", "mypy>=1.11", "ruff>=0.6", "responses>=0.23"]
[project.urls]
Repository = "https://git.netork.io/NAPALM/napalm-redfish"
Issues = "https://git.netork.io/NAPALM/napalm-redfish/issues"
Changelog = "https://git.netork.io/NAPALM/napalm-redfish/src/branch/main/CHANGELOG.md"
[project.entry-points."napalm.drivers"]
redfish = "napalm_redfish:RedfishDriver"
@@ -37,8 +40,8 @@ bmc = "napalm_redfish.bmc:BmcDriver"
[tool.setuptools.packages.find]
include = ["napalm_redfish*"]
[tool.pytest.ini_options]
testpaths = ["tests"]
[tool.setuptools.package-data]
napalm_redfish = ["py.typed"]
[tool.ruff]
line-length = 100
@@ -50,3 +53,38 @@ select = ["E", "F", "I", "UP", "B"]
[tool.ruff.lint.per-file-ignores]
# Recorded device output keeps its lines.
"tests/**" = ["E501"]
[tool.mypy]
python_version = "3.10"
strict = true
# napalm itself is untyped, so every driver subclasses Any.
disallow_subclassing_any = false
[[tool.mypy.overrides]]
module = ["napalm.*", "redfish.*", "pyghmi.*", "requests.*"]
ignore_missing_imports = true
[[tool.mypy.overrides]]
# Not yet under strict mypy (quality baseline); may only shrink.
module = [
"napalm_redfish.bmc",
"napalm_redfish.driver",
"napalm_redfish.ipmi",
"napalm_redfish.parsers.common",
"napalm_redfish.parsers.environment",
"napalm_redfish.parsers.manager",
"napalm_redfish.parsers.system",
"napalm_redfish.transport",
]
ignore_errors = true
[tool.pytest.ini_options]
testpaths = ["tests"]
# The tests import their helpers as tests.conftest, also under a bare pytest.
pythonpath = ["."]
[tool.coverage.run]
source = ["napalm_redfish"]
[tool.coverage.report]
fail_under = 94
+25
View File
@@ -0,0 +1,25 @@
{
"coverage_floor": 94.0,
"function_complexity": {
"napalm_redfish/driver.py::RedfishDriver._accepted_actions": 14,
"napalm_redfish/driver.py::RedfishDriver.get_environment": 14,
"napalm_redfish/driver.py::RedfishDriver.get_facts": 15,
"napalm_redfish/parsers/environment.py::build_environment": 13,
"napalm_redfish/parsers/manager.py::parse_network_protocol": 14,
"napalm_redfish/transport.py::RedfishTransport._request": 14,
"napalm_redfish/transport.py::RedfishTransport.members": 15
},
"function_lines": {},
"mypy_relaxed": [
"napalm_redfish.bmc",
"napalm_redfish.driver",
"napalm_redfish.ipmi",
"napalm_redfish.parsers.common",
"napalm_redfish.parsers.environment",
"napalm_redfish.parsers.manager",
"napalm_redfish.parsers.system",
"napalm_redfish.transport"
],
"python_file_lines": {},
"untyped_public": []
}