fix(get_config): use SSHClient.connect() without algorithm overrides

The SSH console link works on this switch using plain paramiko
SSHClient.connect() with no disabled_algorithms and no Transport hacks.
Our previous approaches (Transport._preferred_kex, socket-level timeout)
were breaking the negotiation. Revert to the simple approach that works.
This commit is contained in:
Christian Manivong
2026-06-29 14:50:34 +02:00
parent f7eff4b3ca
commit a496f02aa9
+18 -36
View File
@@ -592,50 +592,32 @@ class ProcurveDriver(ConfigLifecycleMixin, SwitchDriver):
Used as fallback when the REST API does not expose the config endpoint Used as fallback when the REST API does not expose the config endpoint
(e.g. HP 2530 / YA firmware with Mocana SSH). (e.g. HP 2530 / YA firmware with Mocana SSH).
Uses a raw socket with settimeout() so the timeout covers ALL phases of Uses SSHClient.connect() with the same approach as the netOrk SSH
the SSH handshake (TCP connect, banner, KEX, auth) — not just TCP connect. console link (_paramiko_connect in _helpers.py) — no algorithm
This is the only reliable way to prevent a hanging KEX from blocking overrides, plain password auth, 15-second banner timeout.
indefinitely inside the poll task.
""" """
import socket as _socket
import paramiko import paramiko
_FALLBACK_TIMEOUT = 8 # seconds — covers the entire SSH session _TIMEOUT = 15
_LEGACY_KEX = [
"diffie-hellman-group1-sha1",
"diffie-hellman-group14-sha1",
"diffie-hellman-group14-sha256",
]
try: try:
sock = _socket.create_connection( client = paramiko.SSHClient()
(self.hostname, self.port or 22), client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
timeout=_FALLBACK_TIMEOUT, client.connect(
) hostname=self.hostname,
sock.settimeout(_FALLBACK_TIMEOUT) # applies to all recv/send including KEX port=self.port or 22,
transport = paramiko.Transport(sock)
transport.get_security_options().kex = _LEGACY_KEX
transport.connect(
username=self.username, username=self.username,
password=self.password, password=self.password,
timeout=_TIMEOUT,
banner_timeout=_TIMEOUT,
auth_timeout=_TIMEOUT,
look_for_keys=False,
allow_agent=False,
) )
_, stdout, _ = client.exec_command("show running-config", timeout=_TIMEOUT)
channel = transport.open_session() config = stdout.read().decode("utf-8", errors="replace")
channel.settimeout(_FALLBACK_TIMEOUT) client.close()
channel.exec_command("show running-config") return config
chunks: list[bytes] = []
while True:
data = channel.recv(4096)
if not data:
break
chunks.append(data)
transport.close()
return b"".join(chunks).decode("utf-8", errors="replace")
except Exception as exc: except Exception as exc:
logger.warning("SSH config fallback failed for %s: %s", self.hostname, exc) logger.warning("SSH config fallback failed for %s: %s", self.hostname, exc)
return "" return ""