- The distribution is renamed to napalm-netgear-switches: napalm-netgear
on PyPI belongs to another project. The import package napalm_netgear
and the napalm.drivers entry points netgear_smart and netgear_plus stay;
[tool.napalm-standard] package names the import package for the check.
README install line and CHANGELOG say the new name.
- CI moves to .gitea/workflows/ci.yml and calls the shared driver workflow
of NAPALM/driver-standard; .github/ is gone.
- requires-python >=3.10 (napalm-device-types needs it), floor
napalm-device-types>=4.21.1, LICENSE file, py.typed, SPDX license string,
links to git.netork.io, a dev extra with floors, CHANGELOG.md.
- mypy strict for the package; napalm_netgear.netgear_plus and
napalm_netgear.netgear_smart are exempt for now (139 errors), recorded
in the quality baseline with their long and complex functions and the
2070-line netgear_smart module. Coverage floor 48 % (measured 48.23 %).
Closes#14
- Netgear Plus: a failed logout on close() now logs at debug level (B110),
so a swallowed failure leaves a trace; the module gets its logger.
- nosec for the firmware CDN probe (B310): the URL is built on the fixed
https base _FW_CDN_BASE, model and version only fill its path, so no
file:// or custom scheme can reach urlopen.
- nosec for the empty password in get_users (B105): it is NAPALM's field,
the CLI never shows a password; a false positive.
- The v7 LLDP table in a docstring loses one leading space per line to fit
line length 100.
- tests: a second TestGetLldpNeighbors class shadowed the first, whose two
tests never ran; the v7 one is now TestGetLldpNeighborsV7 and both run
(and pass). raise ... from exc in the netmiko stand-in.
Mechanical: ruff format, and ruff check --fix with the rule set every NAPALM
driver uses (E, F, I, UP, B at line length 100, Python 3.10). What ruff
cannot fix comes in the next commit.
The driver accepted any SSH host key. It now verifies through
napalm-device-types' HostKeyCheck (>= 4.19.0): with a known key in
optional_args["ssh_host_keys"] any other key is refused before login, and
every key seen is reported to optional_args["ssh_host_key_observer"].
Without either argument it connects as before (first use).
The Plus driver looked the newest firmware up in Netgear's download
catalogue and named firmware_update_available itself. It now reports
get_firmware_offer() (napalm-device-types 4.16 FirmwareOfferMixin): what
runs, the newest offered, whether that is newer by Netgear's versioning,
and the download link; netOrk names the warning (netOrk #1111). The Smart
driver's empty get_device_warnings goes too. Requires
napalm-device-types 4.16.0.
fix_snmp hard-coded community "public" and sent its config-mode line
through _send_command, which waits for the exec prompt: in config mode
it ran into its timeout and left the session there (#6).
netgear_smart implements napalm-device-types 4.13's configure_snmp_agent
steps: community (read-only), contact and location from the caller
through _apply_config_lines, which waits for any prompt and reports a
refused line; config mode is left in all cases; the configuration is
saved and the community checked in show snmp. v7 firmware, which has
no SNMP commands in its CLI, says so. A value that would break the CLI
is refused.
napalm-device-types is now declared in pyproject.toml and
requirements.txt (#7).
BREAKING CHANGE: run_device_action is removed.
Closes#6. Part of #7 and #8.
netgear_smart no longer collects over SNMP. SNMP_HEALTH_PROFILE states
where the switch publishes uptime (standard sysUpTime), memory (total
and free in KiB) and CPU (a text value whose five-second figure
counts); the application polls and computes (napalm-device-types
docs/STRUCTURE.md).
Interface counters now come from the 64-bit ifXTable where the switch
has it, as the application reads them for every device.
get_lldp_neighbors() existed but spoke to the older CLI generation: it ran
`show lldp remote-device all` and expected FASTPATH-style `0/1` ports in
whitespace-separated columns. v7 firmware answers `Unknown command` — as it
does for `show lldp remote-device`, a bare `show lldp`, and the plural
`show lldp neighbors`. Only the singular works, though `show ?` lists `lldp`
plainly enough:
Port | Device ID | Port ID | SysName | ...
---- + ----------------- + ---------------- + ----------------- + ...
g9 | 10:01:02:44:37:26 |10:01:02:44:37:28 | pve-eze.eze.local | ...
Ports are named g9, and the columns are separated by `|` with irregular
padding, so splitting on whitespace tears the values apart. The port ID is
not always a port name either — a neighbour may identify its port by MAC.
_get_lldp_table() now branches on _detect_cli_v7() into a second parser, the
same shape get_mac_address_table() already uses for this divergence.
get_lldp_neighbors() itself is untouched.
Confirmed against a GS110TPv3 on 7.1.1.17: _detect_cli_v7() returns True
there, and the switch reports two neighbours it had never surfaced. Without
them NetOrk's map had nothing to draw for the site this switch serves, so
four APs and a firewall behind it stood unconnected.
`show running-config` is preceded by a header block, and one of its lines
reports the system uptime. That value necessarily differs between any two
reads, so every caller comparing consecutive configs sees a change each
time.
Measured on a GS110TPv3 under NetOrk: 876 of 894 stored config snapshots
marked as changed, one git commit and one config_changed warning per poll,
while every other device at the same installation sat between 2 and 18. The
history was worthless for that switch — a genuine change would have been
invisible among hundreds of uptime diffs.
Only the uptime line is removed. Model, firmware version, serial and MAC are
stable and belong in a config backup; a changed firmware version is exactly
the kind of change worth recording.
netgear_plus is unaffected — its get_config() returns empty strings.
The first read after this lands reports one real change, since the line
disappears from the stored config. That is unavoidable and happens once.
"v7" CLI firmware has no "terminal length 0" equivalent (see
_send_paged_command's docstring), so a config long enough to paginate
emits "--More--" prompts that _send_command's expect_string=base_prompt
match never sees. On real hardware (GS110TPv3, 7 VLANs, 10 interfaces)
this hung every scheduled config-backup poll for 30s and failed with
"Pattern not detected: '<prompt>[>#]' in output.", so the config was
never actually backed up. get_mac_address_table()/get_vlans() already
use _send_paged_command() for the same reason on other long outputs;
get_config() now does too.
Also fixed tests/unit/test_driver.py's import/patch target
(napalm_netgear_plus -> napalm_netgear, the actual package name) —
the whole file has been uncollectable since its initial commit, no CI
was wired up here to catch it. And removed a dead unreachable
`return {"success": ..., "output": ...}` line after get_health_metrics's
real return (undefined names, ruff F821), unrelated leftover found
while fixing the above.