Files
Nexus/server/infrastructure/ssh/resolve_server_auth.py
T
r 45ca57bf3f fix(ssh): 连接前从 preset_id 解析 SSH 密码
修复宝塔批量引导因仅关联密码预设、行内 password 为空而全部 ssh_command_failed。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-21 09:47:22 +08:00

58 lines
2.5 KiB
Python

"""Resolve SSH auth from password/SSH-key presets when server row has no inline secret."""
from __future__ import annotations
import logging
from server.domain.models import Server
logger = logging.getLogger("nexus.ssh.resolve_auth")
def _has_inline_ssh_auth(server: Server) -> bool:
if server.ssh_key_path:
return True
if server.ssh_key_configured and server.ssh_key_private:
return True
if server.auth_method == "password" and server.password:
return True
if server.password and server.auth_method != "key":
return True
return False
async def materialize_server_ssh_auth(server: Server) -> None:
"""Load ``preset_id`` / ``ssh_key_preset_id`` into ``server`` for SSH pool use."""
if _has_inline_ssh_auth(server):
return
if not server.preset_id and not server.ssh_key_preset_id:
return
from server.infrastructure.database.session import AsyncSessionLocal
from server.infrastructure.database.password_preset_repo import PasswordPresetRepositoryImpl
from server.infrastructure.database.ssh_key_preset_repo import SshKeyPresetRepositoryImpl
async with AsyncSessionLocal() as session:
auth_method = (server.auth_method or "password").strip().lower()
if server.preset_id and auth_method == "password":
preset = await PasswordPresetRepositoryImpl(session).get_by_id(server.preset_id)
if preset:
server.password = preset.encrypted_pw
server.auth_method = "password"
server.username = (preset.username or server.username or "root").strip() or "root"
logger.debug("SSH auth from password preset id=%s server=%s", preset.id, server.id)
return
logger.warning("password preset id=%s missing for server=%s", server.preset_id, server.id)
if server.ssh_key_preset_id:
preset = await SshKeyPresetRepositoryImpl(session).get_by_id(server.ssh_key_preset_id)
if preset:
server.ssh_key_private = preset.encrypted_private_key
server.ssh_key_public = preset.public_key or server.ssh_key_public
server.ssh_key_configured = True
server.auth_method = "key"
server.username = (preset.username or server.username or "root").strip() or "root"
logger.debug("SSH auth from ssh_key preset id=%s server=%s", preset.id, server.id)
return
logger.warning("ssh_key preset id=%s missing for server=%s", server.ssh_key_preset_id, server.id)