feat: SNMP support — get_snmp_config(), fix_snmp action, get_device_warnings()
get_snmp_config() uses single 'show snmp-server' command with read_timeout=10 to avoid blocking the poll. fix_snmp configures 'snmp-server community public manager restricted'. get_device_warnings() added (was missing, caused AttributeError). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
e7d054ea2a
commit
5f780190c7
@@ -994,6 +994,101 @@ class ProcurveDriver(SwitchDriver):
|
||||
"""Return True if a candidate config is loaded."""
|
||||
return self._candidate_config is not None
|
||||
|
||||
# ── SNMP / Health ──────────────────────────────────────────────────────────
|
||||
|
||||
def get_device_warnings(self) -> list:
|
||||
"""Return device warnings. SNMP detection handled by poll task."""
|
||||
return []
|
||||
|
||||
def get_snmp_config(self):
|
||||
"""Return SNMP config if a community is configured on the switch."""
|
||||
try:
|
||||
from napalm_device_types.models import SNMPConfigDict
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
# Use a single command with short read_timeout to avoid blocking the poll.
|
||||
try:
|
||||
out = self._device.send_command(
|
||||
"show snmp-server",
|
||||
expect_string=rf"{re.escape(self._device.base_prompt)}[>#]",
|
||||
read_timeout=10,
|
||||
).strip() if self._device else ""
|
||||
except Exception:
|
||||
return None
|
||||
if not out:
|
||||
return None
|
||||
|
||||
# Parse communities from output
|
||||
community = None
|
||||
for line in out.splitlines():
|
||||
m = re.match(r"\s+(\S+)\s+(Manager|Operator)\s+(Restricted|Unrestricted)", line, re.I)
|
||||
if m:
|
||||
comm = m.group(1)
|
||||
access = m.group(3).lower()
|
||||
if access == "restricted": # read-only — prefer this
|
||||
community = comm
|
||||
break
|
||||
elif community is None:
|
||||
community = comm # fallback to first found
|
||||
|
||||
if not community:
|
||||
return None
|
||||
|
||||
return SNMPConfigDict(running=True, community=community, port=161, version="2c")
|
||||
|
||||
def run_device_action(self, action: str) -> Dict:
|
||||
"""Execute a named action on the switch."""
|
||||
if action == "fix_snmp":
|
||||
return self._action_fix_snmp()
|
||||
raise NotImplementedError(f"Unknown action: {action!r}")
|
||||
|
||||
def _detect_management_vlan(self) -> Optional[int]:
|
||||
"""Find the VLAN that carries this switch's management IP."""
|
||||
try:
|
||||
out = self._send_command("show ip")
|
||||
for line in out.splitlines():
|
||||
# " VLAN8 | 172.22.8.x ..." or similar
|
||||
m = re.search(r"VLAN\s*(\d+)[^|]*\|\s*" + re.escape(self.hostname), line, re.I)
|
||||
if m:
|
||||
return int(m.group(1))
|
||||
# Alternative: "VLAN 8 172.22.8.x"
|
||||
m2 = re.search(r"\bVLAN\s+(\d+)\b.*\b" + re.escape(self.hostname) + r"\b", line, re.I)
|
||||
if m2:
|
||||
return int(m2.group(1))
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
def _action_fix_snmp(self) -> Dict:
|
||||
"""Enable SNMP with community 'public' (read-only) on the ProCurve switch.
|
||||
|
||||
ProCurve/Aruba syntax:
|
||||
snmp-server community "public" manager restricted
|
||||
"""
|
||||
lines: list = []
|
||||
|
||||
self._enter_config_mode()
|
||||
|
||||
# Enable SNMP with read-only community 'public'
|
||||
# ProCurve: manager = standard access level, restricted = read-only
|
||||
self._send_command('snmp-server community "public" manager restricted')
|
||||
lines.append("[config] SNMP community 'public' (manager restricted / read-only) configured.")
|
||||
|
||||
self._exit_config_mode()
|
||||
self._save_config()
|
||||
lines.append("[config] Configuration saved.")
|
||||
|
||||
# Verify
|
||||
out = self._send_command("show snmp-server")
|
||||
success = "public" in out
|
||||
if success:
|
||||
lines.append("[ok] SNMP is active with community 'public'.")
|
||||
else:
|
||||
lines.append(f"[warn] Verification — community not found: {out[:200]}")
|
||||
|
||||
return {"success": success, "output": "\n".join(lines)}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
|
||||
Reference in New Issue
Block a user