feat!: configure_snmp_agent with the caller's values replaces fix_snmp (0.4.0)
CI / test (3.10) (push) Successful in 24s
CI / test (3.11) (push) Successful in 24s
CI / test (3.12) (push) Successful in 24s
CI / test (3.10) (pull_request) Successful in 24s
CI / test (3.11) (pull_request) Successful in 23s
CI / test (3.12) (pull_request) Successful in 24s

fix_snmp hard-coded community "public". The driver implements
napalm-device-types 4.13's configure_snmp_agent as a whole, because
over REST a temporary SSH session has to run the config-mode CLI:
community (read-only), contact and location from the caller, saved
and verified in show snmp-server. The agent is built in and the switch
filters nothing for its management plane; the steps say so instead of
pretending. A value that would break the CLI is refused.

The unused _detect_management_vlan goes with it.

BREAKING CHANGE: run_device_action is removed.

Part of #12 and #6 (the dead helper).
This commit is contained in:
Christian Manivong committed 2026-10-17 08:35:30 +02:00
1 parent 0c0ab7c988
commit 0527cd20c1
2 files changed
+157 -73

No files matched your search

+93
View File
@@ -0,0 +1,93 @@
"""The SNMP agent through napalm-device-types' configure_snmp_agent (netOrk #1105).
fix_snmp hard-coded community "public". The switch's agent is built in and the
switch filters nothing for its own management plane, so of the template's steps
only "configure" (community, contact, location) and "start" (save, verify) do
work here; the caller's values are used as given.
"""
from __future__ import annotations
from unittest.mock import MagicMock
import pytest
from napalm_procurve.procurve import ProcurveDriver
SETTINGS = {
"community": "c0mm",
"allowed_sources": ["10.7.224.20"],
"contact": "ops",
"location": "rack 1",
}
@pytest.fixture
def driver():
d = ProcurveDriver("10.0.0.40", "admin", "pw")
d._transport = "ssh"
d._device = MagicMock()
d.applied: list[str] = []
d._enter_config_mode = MagicMock()
d._exit_config_mode = MagicMock()
d._save_config = MagicMock()
d._apply_config_lines = lambda text: d.applied.append(text) or []
d._send_command = MagicMock(
return_value=" Community Name MIB View Write Access\n c0mm Manager Restricted\n"
)
return d
def test_community_contact_and_location_are_the_callers(driver):
result = driver.configure_snmp_agent(SETTINGS)
assert result["success"] is True
config = "\n".join(driver.applied)
assert 'snmp-server community "c0mm" manager restricted' in config
assert 'snmp-server contact "ops"' in config
assert 'snmp-server location "rack 1"' in config
assert "public" not in config
driver._save_config.assert_called_once()
def test_the_steps_say_what_the_switch_does_not_do(driver):
result = driver.configure_snmp_agent(SETTINGS)
steps = {s["step"]: s for s in result["steps"]}
assert list(steps) == ["install", "configure", "firewall", "start"]
assert "built in" in steps["install"]["output"]
assert "10.7.224.20" in steps["firewall"]["output"] # not enforced, and said so
def test_a_community_the_switch_does_not_show_afterwards_fails(driver):
driver._send_command.return_value = " Community Name MIB View\n public Manager\n"
assert driver.configure_snmp_agent(SETTINGS)["success"] is False
def test_a_rejected_line_fails_and_nothing_is_saved(driver):
driver._apply_config_lines = lambda text: ["Invalid input: community"]
result = driver.configure_snmp_agent(SETTINGS)
assert result["success"] is False
driver._save_config.assert_not_called()
@pytest.mark.parametrize("community", ["two words", 'q"uote', ""])
def test_a_community_that_would_break_the_cli_is_refused(driver, community):
result = driver.configure_snmp_agent({"community": community, "allowed_sources": []})
assert result["success"] is False
assert driver.applied == []
def test_the_old_action_and_its_dead_helper_are_gone():
gone = (
"run_device_action",
"_action_fix_snmp",
"_action_fix_snmp_cli",
"_detect_management_vlan",
)
for name in gone:
assert not hasattr(ProcurveDriver, name), name