fix: WinRM NTLM username normalize and hostname-first targets (0.10.3)
This commit is contained in:
@@ -29,12 +29,35 @@ class WinRmTestResult:
|
||||
|
||||
|
||||
def resolve_windows_host_target(host: Host) -> str:
|
||||
targets = iter_winrm_targets(host)
|
||||
if not targets:
|
||||
raise HostTargetMissingError("Host has no hostname or IPv4 for WinRM test")
|
||||
return targets[0]
|
||||
|
||||
|
||||
def iter_winrm_targets(host: Host) -> list[str]:
|
||||
"""WinRM + NTLM: сначала имя машины (SPN), затем IPv4."""
|
||||
if not is_windows_host(host):
|
||||
raise HostNotWindowsError("Host is not Windows")
|
||||
target = (host.ipv4 or "").strip() or (host.hostname or "").strip()
|
||||
if not target:
|
||||
raise HostTargetMissingError("Host has no IPv4 or hostname for WinRM test")
|
||||
return target
|
||||
|
||||
seen: set[str] = set()
|
||||
ordered: list[str] = []
|
||||
|
||||
def add(value: str | None) -> None:
|
||||
text = (value or "").strip()
|
||||
if not text or text in seen:
|
||||
return
|
||||
seen.add(text)
|
||||
ordered.append(text)
|
||||
|
||||
inventory = host.inventory if isinstance(host.inventory, dict) else {}
|
||||
computer_name = inventory.get("computer_name")
|
||||
if isinstance(computer_name, str):
|
||||
add(computer_name)
|
||||
add(host.hostname)
|
||||
add(host.display_name)
|
||||
add(host.ipv4)
|
||||
return ordered
|
||||
|
||||
|
||||
def is_windows_host(host: Host) -> bool:
|
||||
@@ -55,6 +78,10 @@ def test_winrm_connection(
|
||||
if not target or not user or not password:
|
||||
raise WinAdminNotConfiguredError("Windows admin credentials or target missing")
|
||||
|
||||
from app.services.win_admin_settings import normalize_win_admin_user
|
||||
|
||||
user = normalize_win_admin_user(user)
|
||||
|
||||
try:
|
||||
import winrm
|
||||
except ImportError as exc:
|
||||
@@ -73,9 +100,16 @@ def test_winrm_connection(
|
||||
)
|
||||
result = session.run_cmd("hostname")
|
||||
except winrm.exceptions.WinRMTransportError as exc:
|
||||
detail = str(exc)
|
||||
hint = ""
|
||||
if "credentials were rejected" in detail.lower():
|
||||
hint = (
|
||||
" Проверьте логин (B26\\user), пароль и что учётка — admin на целевом ПК; "
|
||||
"при подключении по IP NTLM часто отклоняет creds — используйте имя хоста."
|
||||
)
|
||||
return WinRmTestResult(
|
||||
ok=False,
|
||||
message=f"WinRM transport error: {exc}",
|
||||
message=f"WinRM transport error ({target}): {detail}{hint}",
|
||||
target=target,
|
||||
)
|
||||
except (socket.timeout, TimeoutError):
|
||||
|
||||
Reference in New Issue
Block a user