Add SSH connection validation for settings
This commit is contained in:
@@ -48,7 +48,7 @@ class RemoteSSHClient:
|
||||
private_key_passphrase: str | None = None,
|
||||
password: str | None = None,
|
||||
known_hosts_path: str | None = None,
|
||||
timeout: int = 20,
|
||||
timeout: int = 30,
|
||||
):
|
||||
if not host or not username:
|
||||
raise ValueError("SSH host and username are required")
|
||||
@@ -73,7 +73,19 @@ class RemoteSSHClient:
|
||||
if self._client:
|
||||
return self._client
|
||||
if self.known_hosts_path:
|
||||
ensure_known_host(self.host, self.port, Path(self.known_hosts_path), strict=True)
|
||||
try:
|
||||
ensure_known_host(self.host, self.port, Path(self.known_hosts_path), strict=True)
|
||||
except Exception as exc:
|
||||
message = str(exc).lower()
|
||||
if "protocol banner" in message:
|
||||
raise RuntimeError(
|
||||
f"SSH banner not received from {self.host}:{self.port}. "
|
||||
"The host key could not be recorded because the backend could not talk to SSH."
|
||||
) from exc
|
||||
raise RuntimeError(
|
||||
f"SSH host key lookup failed for {self.host}:{self.port}. "
|
||||
"Confirm the host and port are correct and that SSH is reachable."
|
||||
) from exc
|
||||
client = paramiko.SSHClient()
|
||||
client.load_system_host_keys()
|
||||
if self.known_hosts_path and Path(self.known_hosts_path).is_file():
|
||||
@@ -85,12 +97,28 @@ class RemoteSSHClient:
|
||||
"username": self.username,
|
||||
"password": self.password,
|
||||
"timeout": self.timeout,
|
||||
"banner_timeout": self.timeout,
|
||||
"auth_timeout": self.timeout,
|
||||
}
|
||||
if self.private_key:
|
||||
connect_kwargs["pkey"] = self._load_private_key(self.private_key, self.private_key_passphrase)
|
||||
else:
|
||||
connect_kwargs["key_filename"] = self.key_filename
|
||||
client.connect(**connect_kwargs)
|
||||
try:
|
||||
client.connect(**connect_kwargs)
|
||||
except Exception as exc:
|
||||
message = str(exc).lower()
|
||||
if "protocol banner" in message:
|
||||
raise RuntimeError(
|
||||
f"SSH banner not received from {self.host}:{self.port}. "
|
||||
"Confirm the host, port, and firewall; the backend could not complete the SSH handshake."
|
||||
) from exc
|
||||
if "no authentication methods available" in message or "authentication failed" in message:
|
||||
raise RuntimeError(
|
||||
f"SSH authentication failed for {self.host}:{self.port}. "
|
||||
"Check the selected key, passphrase, username, or password."
|
||||
) from exc
|
||||
raise
|
||||
self._client = client
|
||||
return client
|
||||
|
||||
|
||||
Reference in New Issue
Block a user