chore: adopt the NAPALM driver standard #15
No files matched your search
@@ -21,6 +21,7 @@ The ``username`` parameter is accepted but ignored.
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@@ -28,6 +29,8 @@ from typing import Any
|
|||||||
from napalm.base.exceptions import ConnectionException
|
from napalm.base.exceptions import ConnectionException
|
||||||
from napalm_device_types import FingerprintRule, FirmwareOfferMixin, SwitchDriver
|
from napalm_device_types import FingerprintRule, FirmwareOfferMixin, SwitchDriver
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Firmware update check — module-level constants and cache
|
# Firmware update check — module-level constants and cache
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -69,7 +72,8 @@ def _fw_cdn_exists(model: str, version: str) -> bool:
|
|||||||
ctx = ssl.create_default_context()
|
ctx = ssl.create_default_context()
|
||||||
req = urllib.request.Request(url, method="HEAD", headers={"User-Agent": "Mozilla/5.0"})
|
req = urllib.request.Request(url, method="HEAD", headers={"User-Agent": "Mozilla/5.0"})
|
||||||
try:
|
try:
|
||||||
with urllib.request.urlopen(req, timeout=3, context=ctx):
|
# The URL is always https on _FW_CDN_BASE; model and version only fill the path.
|
||||||
|
with urllib.request.urlopen(req, timeout=3, context=ctx): # nosec B310
|
||||||
return True
|
return True
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
@@ -220,7 +224,7 @@ class NetgearPlusDriver(FirmwareOfferMixin, SwitchDriver):
|
|||||||
try:
|
try:
|
||||||
self._connector.delete_login_cookie()
|
self._connector.delete_login_cookie()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
logger.debug("Logging out of the switch failed: ignored", exc_info=True)
|
||||||
self._connector = None
|
self._connector = None
|
||||||
self._switch_infos_cache = None
|
self._switch_infos_cache = None
|
||||||
|
|
||||||
|
|||||||
@@ -1115,9 +1115,9 @@ class NetgearSmartDriver(ConfigLifecycleMixin, SnmpAgentMixin, SwitchDriver):
|
|||||||
``show lldp`` — both answer "Unknown command". Only the singular
|
``show lldp`` — both answer "Unknown command". Only the singular
|
||||||
``neighbor`` works, and it lays the table out differently::
|
``neighbor`` works, and it lays the table out differently::
|
||||||
|
|
||||||
Port | Device ID | Port ID | SysName | Capabilities | TTL
|
Port | Device ID | Port ID | SysName | Capabilities | TTL
|
||||||
---- + ----------------- + ---------------- + ----------------- + -------------- + -----
|
---- + ----------------- + ---------------- + ----------------- + -------------- + -----
|
||||||
g9 | 10:01:02:44:37:26 |10:01:02:44:37:28 | pve-eze.eze.local | Bridge | 97
|
g9 | 10:01:02:44:37:26 |10:01:02:44:37:28 | pve-eze.eze.local | Bridge | 97
|
||||||
|
|
||||||
Ports are named ``g9`` rather than ``0/1``, and the columns are
|
Ports are named ``g9`` rather than ``0/1``, and the columns are
|
||||||
separated by ``|`` with irregular padding — splitting on whitespace
|
separated by ``|`` with irregular padding — splitting on whitespace
|
||||||
@@ -1629,7 +1629,8 @@ class NetgearSmartDriver(ConfigLifecycleMixin, SnmpAgentMixin, SwitchDriver):
|
|||||||
username = parts[0]
|
username = parts[0]
|
||||||
role = parts[1].lower()
|
role = parts[1].lower()
|
||||||
level = 15 if "write" in role or "admin" in role else 1
|
level = 15 if "write" in role or "admin" in role else 1
|
||||||
users[username] = {"level": level, "password": "", "sshkeys": []}
|
# NAPALM's get_users shape: the CLI never shows a password, so it is empty.
|
||||||
|
users[username] = {"level": level, "password": "", "sshkeys": []} # nosec B105
|
||||||
|
|
||||||
return users
|
return users
|
||||||
|
|
||||||
|
|||||||
@@ -745,7 +745,7 @@ GS110TPv3#
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class TestGetLldpNeighbors:
|
class TestGetLldpNeighborsV7:
|
||||||
"""`show lldp neighbor` — the switch does speak LLDP, the driver did not.
|
"""`show lldp neighbor` — the switch does speak LLDP, the driver did not.
|
||||||
|
|
||||||
Without this the map has nothing to draw for the site this switch serves:
|
Without this the map has nothing to draw for the site this switch serves:
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ def test_a_changed_key_is_refused():
|
|||||||
try:
|
try:
|
||||||
raise paramiko.BadHostKeyException("10.0.0.8", SERVER_KEY, OTHER_KEY)
|
raise paramiko.BadHostKeyException("10.0.0.8", SERVER_KEY, OTHER_KEY)
|
||||||
except paramiko.SSHException as exc: # what netmiko does with it
|
except paramiko.SSHException as exc: # what netmiko does with it
|
||||||
raise NetmikoTimeoutException(f"A paramiko SSHException occurred: {exc}")
|
raise NetmikoTimeoutException(f"A paramiko SSHException occurred: {exc}") from exc
|
||||||
|
|
||||||
driver = _driver(seen, SshHostKey.of(OTHER_KEY))
|
driver = _driver(seen, SshHostKey.of(OTHER_KEY))
|
||||||
with patch(HANDLER, side_effect=refuse):
|
with patch(HANDLER, side_effect=refuse):
|
||||||
|
|||||||
Reference in new issue
Block a user