From 95ec6ad33b58c0dac10ad25579d774d6d9868f1c Mon Sep 17 00:00:00 2001 From: Christian Manivong Date: Sat, 17 Oct 2026 00:53:56 +0200 Subject: [PATCH] feat: switch off the fix templates QTS cannot take (0.4.0) napalm-linux 0.8 implements napalm-device-types' fix templates. QTS has no apt, dnf or opkg and sets its SNMP agent in its own UI, so configure_snmp_agent, configure_package_proxy and ensure_package are None here: a capability check answers no instead of offering a fix that fails, as the inherited fix_snmp and fix_apt_proxy did. get_device_warnings returns nothing: the inherited one asked for updates, which is None here, and logged a TypeError on every poll. The role test follows napalm-linux's get_os_users. Closes #6. Part of #7. --- CHANGELOG.md | 12 ++++++++++++ napalm_qnap_qts/qnap_qts.py | 9 +++++++++ pyproject.toml | 4 ++-- tests/test_qnap_qts.py | 23 +++++++++++++++++++++-- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e9beb1..bc3e15d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.4.0] – 2026-10-17 + +### Changed +- Requires napalm-linux 0.8.0, whose fixes are napalm-device-types' templates. + `configure_snmp_agent`, `configure_package_proxy` and `ensure_package` are switched + off (`None`): QTS has no apt, dnf or opkg, and its SNMP agent is set in its own UI. + Before, the inherited SNMP and apt-proxy fixes were offered and failed. + +### Fixed +- `get_device_warnings` no longer logs a TypeError on every poll: the inherited one + asked for updates, which QTS cannot list (#6). + ## [0.3.0] – 2026-10-08 ### Removed diff --git a/napalm_qnap_qts/qnap_qts.py b/napalm_qnap_qts/qnap_qts.py index 03feeb7..f003056 100644 --- a/napalm_qnap_qts/qnap_qts.py +++ b/napalm_qnap_qts/qnap_qts.py @@ -78,6 +78,15 @@ class QnapQtsDriver(StorageDriver, HypervisorDriver, LinuxDriver): get_available_updates = None # type: ignore[assignment] refresh_available_updates = None # type: ignore[assignment] apply_updates = None # type: ignore[assignment] + #: The fix templates LinuxDriver carries need a package manager or net-snmp + #: from packages; QTS has neither, and its SNMP agent is set in its own UI. + configure_snmp_agent = None # type: ignore[assignment] + configure_package_proxy = None # type: ignore[assignment] + ensure_package = None # type: ignore[assignment] + + def get_device_warnings(self) -> list: + """Nothing to report: the inherited one asks for updates QTS cannot list.""" + return [] SNMP_OBJECT_ID_PREFIX = QNAP_ENTERPRISE_OID SNMP_FINGERPRINT = [ diff --git a/pyproject.toml b/pyproject.toml index 81f2852..a783f86 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "napalm-qnap-qts" -version = "0.3.0" +version = "0.4.0" description = "NAPALM driver for QNAP NAS systems running QTS via SSH" readme = "README.md" requires-python = ">=3.9" @@ -44,7 +44,7 @@ classifiers = [ dependencies = [ "napalm>=4.0", "napalm-device-types>=2.6.0", - "napalm-linux>=0.3.0", + "napalm-linux>=0.8.0", "netmiko>=4.0.0", "paramiko>=5.0.0", # CVE-2026-44405 ] diff --git a/tests/test_qnap_qts.py b/tests/test_qnap_qts.py index 8066664..c5f9dfa 100644 --- a/tests/test_qnap_qts.py +++ b/tests/test_qnap_qts.py @@ -10,8 +10,8 @@ from __future__ import annotations from unittest.mock import MagicMock, patch import pytest - from napalm_device_types import primary_role_of, role_keys_of + from napalm_qnap_qts import QnapQtsDriver #: Parsers need real command output to be written against. These tests are the @@ -97,7 +97,7 @@ class TestRolesDoNotShadowLinux: collision. There is nothing left to collide with. """ - @pytest.mark.parametrize("method", ["get_services", "get_users"]) + @pytest.mark.parametrize("method", ["get_services", "get_os_users"]) def test_os_surface_resolves_to_linux(self, method): """QTS really is Linux for these, so inheriting them is correct.""" from napalm_linux.linux import LinuxDriver @@ -224,3 +224,22 @@ def test_updates_are_not_read_or_applied_here(): methods are callable.""" for method in ("get_available_updates", "refresh_available_updates", "apply_updates"): assert not callable(getattr(QnapQtsDriver, method, None)), method + + +class TestFixesQtsCannotTake: + """QTS has no apt, dnf or opkg, and its SNMP agent is configured in its own UI: + the fix templates inherited from LinuxDriver are switched off (#7), so a + capability check -- is it callable? -- answers no.""" + + @pytest.mark.parametrize( + "name", ["configure_snmp_agent", "configure_package_proxy", "ensure_package"] + ) + def test_switched_off(self, name): + assert getattr(QnapQtsDriver, name) is None + + +def test_device_warnings_do_not_ask_for_updates_qts_cannot_list(): + """The inherited get_device_warnings called get_available_updates, which is + None here, and logged a TypeError on every poll (#6).""" + driver = QnapQtsDriver("nas", "admin", "pw") + assert driver.get_device_warnings() == [] -- 2.54.0