chore: adopt the NAPALM driver standard #3

Merged
christianmanivong merged 4 commits from chore/driver-standard into main 2026-10-23 09:36:20 +00:00
7 changed files with 109 additions and 18 deletions
Showing only changes of commit 8dac2e67dd - Show all commits

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/ dist/
.venv/ .venv/
.pytest_cache/ .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] ## [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 ## [0.5.0] - 2026-10-17
### Added ### 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 - Parsing lives in pure functions, tested on recorded responses under
`tests/fixtures/<vendor>-<model>-<firmware>/`, with a `COMMANDS.txt` (here: the request `tests/fixtures/<vendor>-<model>-<firmware>/`, with a `COMMANDS.txt` (here: the request
paths) listing what produced each file. 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 ## Usage
@@ -104,11 +102,12 @@ to basic auth only if the service cannot create sessions), `retries` (1).
## Development ## Development
The rules are in [STANDARDS.md](https://git.netork.io/NAPALM/driver-standard/src/branch/main/STANDARDS.md).
```bash ```bash
python -m venv .venv && . .venv/bin/activate python -m venv .venv && . .venv/bin/activate
pip install git+https://git.netork.io/NAPALM/napalm-device-types.git pip install -e '.[dev]'
pip install -e '.[test]' pytest --cov
pytest
``` ```
Fixtures from the DMTF mockups live under `tests/fixtures/dmtf-<mockup>/`, unmodified, with 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] [build-system]
requires = ["setuptools>=64"] requires = ["setuptools>=77"]
build-backend = "setuptools.build_meta" build-backend = "setuptools.build_meta"
[project] [project]
@@ -7,27 +7,30 @@ name = "napalm-redfish"
version = "0.5.0" version = "0.5.0"
description = "NAPALM driver for server baseboard management controllers over DMTF Redfish" description = "NAPALM driver for server baseboard management controllers over DMTF Redfish"
readme = "README.md" readme = "README.md"
license = { file = "LICENSE" } license = "Apache-2.0"
requires-python = ">=3.10" requires-python = ">=3.10"
dependencies = [ dependencies = [
"napalm>=5.0", "napalm>=5.0",
# Not on PyPI: install from git before this package (see README). "napalm-device-types>=4.21.1",
"napalm-device-types>=4.15", # Before 3.4.1, max_retry=0 (retries=0) gets no response back at all.
"redfish>=3.2", "redfish>=3.4.1",
"pyghmi>=1.5", # 1.5.0 imports python-dateutil without declaring it.
"pyghmi>=1.5.1",
] ]
classifiers = [ classifiers = [
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Topic :: System :: Hardware", "Topic :: System :: Hardware",
"Topic :: System :: Networking", "Topic :: System :: Networking",
] ]
[project.optional-dependencies] [project.optional-dependencies]
test = [ # responses mocks the BMC's HTTP answers in the tests.
"pytest>=7", dev = ["pytest>=8", "pytest-cov>=5", "mypy>=1.11", "ruff>=0.6", "responses>=0.23"]
"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"] [project.entry-points."napalm.drivers"]
redfish = "napalm_redfish:RedfishDriver" redfish = "napalm_redfish:RedfishDriver"
@@ -37,8 +40,8 @@ bmc = "napalm_redfish.bmc:BmcDriver"
[tool.setuptools.packages.find] [tool.setuptools.packages.find]
include = ["napalm_redfish*"] include = ["napalm_redfish*"]
[tool.pytest.ini_options] [tool.setuptools.package-data]
testpaths = ["tests"] napalm_redfish = ["py.typed"]
[tool.ruff] [tool.ruff]
line-length = 100 line-length = 100
@@ -50,3 +53,38 @@ select = ["E", "F", "I", "UP", "B"]
[tool.ruff.lint.per-file-ignores] [tool.ruff.lint.per-file-ignores]
# Recorded device output keeps its lines. # Recorded device output keeps its lines.
"tests/**" = ["E501"] "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": []
}