фикс отвала при успешной авторизации

This commit is contained in:
dv 2026-04-29 12:46:15 +03:00
parent 8d9ebc0446
commit 54c851ce8d
2 changed files with 50 additions and 21 deletions

View file

@ -84,21 +84,35 @@ async def ssh_run_multi(
_log_attempt(i, len(options), host, opt) _log_attempt(i, len(options), host, opt)
try: try:
connect_kwargs = _build_connect_kwargs(host, port, opt) connect_kwargs = _build_connect_kwargs(host, port, opt)
async with asyncssh.connect(**connect_kwargs) as conn: conn = await asyncssh.connect(**connect_kwargs)
result = await asyncio.wait_for(
conn.run(command, check=True), timeout=timeout
)
logger.info(
"[discovery] SSH auth succeeded for %s with %s(%s)",
host, opt.type, opt.username,
)
return result.stdout
except Exception as exc: except Exception as exc:
last_exc = exc last_exc = exc
logger.info( logger.info(
"[discovery] SSH auth failed for %s with %s(%s): %s", "[discovery] SSH auth failed for %s with %s(%s): %s",
host, opt.type, opt.username, exc, host, opt.type, opt.username, exc,
) )
continue
logger.info(
"[discovery] SSH auth succeeded for %s with %s(%s)",
host, opt.type, opt.username,
)
try:
async with conn:
result = await asyncio.wait_for(
conn.run(command, check=True), timeout=timeout
)
return result.stdout
except asyncio.TimeoutError as exc:
err = TimeoutError(f"SSH command timed out after {timeout}s on {host}: {command}")
logger.warning("[discovery] %s", err)
raise err from exc
except Exception as exc:
logger.warning(
"[discovery] SSH command failed on %s after auth with %s(%s): %s",
host, opt.type, opt.username, exc,
)
raise
raise last_exc raise last_exc

View file

@ -251,21 +251,10 @@ async def _try_connect(
try: try:
conn = await asyncio.wait_for(asyncssh.connect(**connect_kwargs), timeout=15) conn = await asyncio.wait_for(asyncssh.connect(**connect_kwargs), timeout=15)
async with conn:
result = await asyncio.wait_for(conn.run(command, check=False), timeout=timeout)
duration = int((time.monotonic() - start) * 1000)
return SSHResult(
success=result.exit_status == 0,
stdout=(result.stdout or "").strip(),
stderr=(result.stderr or "").strip(),
exit_code=result.exit_status or 0,
duration_ms=duration,
auth_ok=True, # Connection was established — auth succeeded
)
except asyncio.TimeoutError: except asyncio.TimeoutError:
return SSHResult( return SSHResult(
success=False, success=False,
error="Connection timed out", error="SSH connection timed out",
duration_ms=int((time.monotonic() - start) * 1000), duration_ms=int((time.monotonic() - start) * 1000),
) )
except (asyncssh.DisconnectError, asyncssh.PermissionDenied, asyncssh.ConnectionLost) as e: except (asyncssh.DisconnectError, asyncssh.PermissionDenied, asyncssh.ConnectionLost) as e:
@ -281,6 +270,32 @@ async def _try_connect(
duration_ms=int((time.monotonic() - start) * 1000), duration_ms=int((time.monotonic() - start) * 1000),
) )
try:
async with conn:
result = await asyncio.wait_for(conn.run(command, check=False), timeout=timeout)
duration = int((time.monotonic() - start) * 1000)
return SSHResult(
success=result.exit_status == 0,
stdout=(result.stdout or "").strip(),
stderr=(result.stderr or "").strip(),
exit_code=result.exit_status or 0,
duration_ms=duration,
auth_ok=True,
)
except asyncio.TimeoutError:
return SSHResult(
success=False,
error=f"SSH command timed out after {timeout}s",
duration_ms=int((time.monotonic() - start) * 1000),
auth_ok=True,
)
except Exception as e:
return SSHResult(
success=False,
error=str(e),
duration_ms=int((time.monotonic() - start) * 1000),
auth_ok=True,
)
async def _save_last_auth(device: Device, db: AsyncSession, opt: _AuthOption) -> None: async def _save_last_auth(device: Device, db: AsyncSession, opt: _AuthOption) -> None:
"""Persist the successful auth method to device.ssh_last_auth.""" """Persist the successful auth method to device.ssh_last_auth."""