"""NAPALM driver for Example switches over SSH. Optional args ------------- port : int SSH port (default 22). """ from __future__ import annotations import logging from typing import Any, Protocol from napalm.base.exceptions import ConnectionException from napalm.base.models import FactsDict from napalm_device_types import SwitchDriver from napalm_example.parsers import parse_version LOG = logging.getLogger(__name__) VENDOR = "Example" DEFAULT_PORT = 22 class Transport(Protocol): def command(self, line: str) -> str: ... def close(self) -> None: ... class ExampleDriver(SwitchDriver): """A switch that answers line commands over SSH.""" def __init__( self, hostname: str, username: str, password: str, timeout: int = 60, optional_args: dict[str, Any] | None = None, ) -> None: self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.port = int((optional_args or {}).get("port", DEFAULT_PORT)) self.transport: Transport | None = None def open(self) -> None: # pragma: no cover - live I/O from netmiko import ConnectHandler session = ConnectHandler( device_type="generic", host=self.hostname, port=self.port, username=self.username, password=self.password, timeout=self.timeout, ) class _Netmiko: def command(self, line: str) -> str: return str(session.send_command(line)) def close(self) -> None: session.disconnect() self.transport = _Netmiko() def close(self) -> None: if self.transport is not None: self.transport.close() self.transport = None def _command(self, line: str) -> str: if self.transport is None: raise ConnectionException(f"{self.hostname}: not connected; call open() first") LOG.debug("%s: %s", self.hostname, line) return self.transport.command(line) def get_facts(self) -> FactsDict: version = parse_version(self._command("show version")) return { "vendor": VENDOR, "model": version["model"], "hostname": version["hostname"], "fqdn": version["hostname"], "os_version": version["os_version"], "serial_number": version["serial_number"], "uptime": version["uptime"], "interface_list": [], }