fix: WinRM RDP update via NETLOGON Deploy, git fallback (0.20.12)
This commit is contained in:
@@ -192,6 +192,9 @@ def run_windows_agent_update_fallback(
|
||||
host: Host,
|
||||
cfg_win,
|
||||
script_path: str,
|
||||
*,
|
||||
repo_url: str = "",
|
||||
git_branch: str = "main",
|
||||
) -> AgentUpdateFallbackResult:
|
||||
if not is_windows_host(host):
|
||||
return AgentUpdateFallbackResult(ok=False, message="Host is not Windows", product_version=None)
|
||||
@@ -216,6 +219,8 @@ def run_windows_agent_update_fallback(
|
||||
user=cfg_win.user,
|
||||
password=cfg_win.password,
|
||||
script_path=script_path,
|
||||
repo_url=repo_url,
|
||||
git_branch=git_branch,
|
||||
),
|
||||
)
|
||||
if result is None:
|
||||
@@ -256,7 +261,13 @@ def execute_agent_update_fallback(db: Session, host: Host) -> AgentUpdateFallbac
|
||||
)
|
||||
elif product == PRODUCT_RDP or is_windows_host(host):
|
||||
win_cfg = get_effective_win_admin_config(db)
|
||||
result = run_windows_agent_update_fallback(host, win_cfg, cfg.win_agent_update_script)
|
||||
result = run_windows_agent_update_fallback(
|
||||
host,
|
||||
win_cfg,
|
||||
cfg.win_agent_update_script,
|
||||
repo_url=cfg.rdp_git_repo_url,
|
||||
git_branch=cfg.git_branch,
|
||||
)
|
||||
else:
|
||||
return AgentUpdateFallbackResult(
|
||||
ok=False,
|
||||
|
||||
@@ -289,29 +289,75 @@ def _wrap_powershell_body(body: str) -> str:
|
||||
)
|
||||
|
||||
|
||||
def _rdp_update_powershell_script(script_path: str) -> str:
|
||||
def _rdp_update_powershell_script(
|
||||
script_path: str,
|
||||
*,
|
||||
repo_url: str = "",
|
||||
git_branch: str = "main",
|
||||
) -> str:
|
||||
script = script_path.strip()
|
||||
if script:
|
||||
literal = _powershell_literal_path(script)
|
||||
body = (
|
||||
f"$p = '{literal}'\n"
|
||||
"if (-not (Test-Path -LiteralPath $p)) { throw \"Deploy script not found: $p\" }\n"
|
||||
"& $p"
|
||||
)
|
||||
else:
|
||||
body = (
|
||||
"$candidates = @(\n"
|
||||
" (Join-Path $env:ProgramData 'RDP-login-monitor\\Deploy-LoginMonitor.ps1'),\n"
|
||||
" (Join-Path $env:ProgramData 'LoginMonitor\\Deploy-LoginMonitor.ps1'),\n"
|
||||
" (Join-Path $env:USERPROFILE 'Deploy-LoginMonitor.ps1')\n"
|
||||
")\n"
|
||||
"$p = $candidates | Where-Object { Test-Path -LiteralPath $_ } | Select-Object -First 1\n"
|
||||
"if (-not $p) { throw 'Deploy-LoginMonitor.ps1 not found on client PC' }\n"
|
||||
"Write-Output \"Running: $p\"\n"
|
||||
"& $p"
|
||||
)
|
||||
return _wrap_powershell_body(body)
|
||||
|
||||
safe_repo = _powershell_literal_path(
|
||||
(repo_url or "https://git.kalinamall.ru/PapaTramp/RDP-login-monitor.git").strip()
|
||||
)
|
||||
safe_branch = _powershell_literal_path((git_branch or "main").strip() or "main")
|
||||
body = (
|
||||
"function Invoke-RdpDeploy {\n"
|
||||
" param([string]$Path)\n"
|
||||
" Write-Output \"Running: $Path\"\n"
|
||||
" & $Path\n"
|
||||
"}\n"
|
||||
"$deployCandidates = [System.Collections.Generic.List[string]]::new()\n"
|
||||
"if ($env:USERDOMAIN) {\n"
|
||||
" $deployCandidates.Add((Join-Path \"\\\\$($env:USERDOMAIN)\\NETLOGON\\RDP-login-monitor\" 'Deploy-LoginMonitor.ps1'))\n"
|
||||
"}\n"
|
||||
"try {\n"
|
||||
" $dom = (Get-CimInstance Win32_ComputerSystem -ErrorAction Stop).Domain\n"
|
||||
" if ($dom) {\n"
|
||||
" $deployCandidates.Add((Join-Path \"\\\\$dom\\NETLOGON\\RDP-login-monitor\" 'Deploy-LoginMonitor.ps1'))\n"
|
||||
" }\n"
|
||||
"} catch { }\n"
|
||||
"foreach ($p in $deployCandidates) {\n"
|
||||
" if (Test-Path -LiteralPath $p) {\n"
|
||||
" Invoke-RdpDeploy $p\n"
|
||||
" exit 0\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
f"$gitUrl = '{safe_repo}'\n"
|
||||
f"$branch = '{safe_branch}'\n"
|
||||
"$repoDir = Join-Path $env:ProgramData 'RDP-login-monitor\\_sac_git'\n"
|
||||
"$gitCmd = Get-Command git.exe -ErrorAction SilentlyContinue\n"
|
||||
"if (-not $gitCmd) {\n"
|
||||
" throw 'Deploy-LoginMonitor.ps1 not on NETLOGON and git.exe missing; set win_agent_update_script in SAC or install Git'\n"
|
||||
"}\n"
|
||||
"if (-not (Test-Path -LiteralPath (Join-Path $repoDir '.git'))) {\n"
|
||||
" if (Test-Path -LiteralPath $repoDir) { Remove-Item -LiteralPath $repoDir -Recurse -Force }\n"
|
||||
" New-Item -ItemType Directory -Path (Split-Path $repoDir -Parent) -Force | Out-Null\n"
|
||||
" & git.exe clone -b $branch $gitUrl $repoDir\n"
|
||||
" if ($LASTEXITCODE -ne 0) { throw \"git clone failed (exit $LASTEXITCODE)\" }\n"
|
||||
"} else {\n"
|
||||
" Push-Location $repoDir\n"
|
||||
" & git.exe fetch origin\n"
|
||||
" & git.exe reset --hard \"origin/$branch\"\n"
|
||||
" $code = $LASTEXITCODE\n"
|
||||
" Pop-Location\n"
|
||||
" if ($code -ne 0) { throw \"git reset failed (exit $code)\" }\n"
|
||||
"}\n"
|
||||
"$deploy = Join-Path $repoDir 'Deploy-LoginMonitor.ps1'\n"
|
||||
"if (-not (Test-Path -LiteralPath $deploy)) { throw \"Deploy-LoginMonitor.ps1 missing in git checkout: $repoDir\" }\n"
|
||||
"& $deploy -SourceShareRoot $repoDir\n"
|
||||
)
|
||||
return _wrap_powershell_body(body)
|
||||
|
||||
|
||||
def run_winrm_rdp_monitor_update(
|
||||
*,
|
||||
@@ -319,12 +365,18 @@ def run_winrm_rdp_monitor_update(
|
||||
user: str,
|
||||
password: str,
|
||||
script_path: str = "",
|
||||
repo_url: str = "",
|
||||
git_branch: str = "main",
|
||||
) -> WinRmCmdResult:
|
||||
return run_winrm_ps(
|
||||
target=target,
|
||||
user=user,
|
||||
password=password,
|
||||
script=_rdp_update_powershell_script(script_path),
|
||||
script=_rdp_update_powershell_script(
|
||||
script_path,
|
||||
repo_url=repo_url,
|
||||
git_branch=git_branch,
|
||||
),
|
||||
timeout_sec=900,
|
||||
)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""Единый источник версии SAC (API, health, логи, OpenAPI)."""
|
||||
|
||||
APP_NAME = "Security Alert Center"
|
||||
APP_VERSION = "0.20.11"
|
||||
APP_VERSION = "0.20.12"
|
||||
APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}"
|
||||
|
||||
@@ -7,17 +7,29 @@ from app.services.winrm_connect import (
|
||||
)
|
||||
|
||||
|
||||
def test_rdp_update_default_script_uses_rdp_login_monitor_path():
|
||||
def test_rdp_update_default_script_uses_netlogon_and_git_fallback():
|
||||
script = _rdp_update_powershell_script("")
|
||||
assert "$ProgressPreference = 'SilentlyContinue'" in script
|
||||
assert "try {" in script
|
||||
assert "Write-Output ('ERROR: '" in script
|
||||
assert "RDP-login-monitor\\Deploy-LoginMonitor.ps1" in script
|
||||
assert "NETLOGON\\RDP-login-monitor" in script
|
||||
assert "Deploy-LoginMonitor.ps1" in script
|
||||
assert "_sac_git" in script
|
||||
assert "git.kalinamall.ru/PapaTramp/RDP-login-monitor.git" in script
|
||||
assert "ProgramData\\RDP-login-monitor\\Deploy-LoginMonitor.ps1" not in script
|
||||
|
||||
|
||||
def test_rdp_update_default_script_honors_sac_git_settings():
|
||||
script = _rdp_update_powershell_script(
|
||||
"",
|
||||
repo_url="https://git.example.com/org/rdp.git",
|
||||
git_branch="release",
|
||||
)
|
||||
assert "git.example.com/org/rdp.git" in script
|
||||
assert "$branch = 'release'" in script
|
||||
|
||||
|
||||
def test_rdp_update_custom_script_uses_literal_path():
|
||||
script = _rdp_update_powershell_script(r"C:\ProgramData\RDP-login-monitor\Deploy-LoginMonitor.ps1")
|
||||
assert r"C:\ProgramData\RDP-login-monitor\Deploy-LoginMonitor.ps1" in script
|
||||
script = _rdp_update_powershell_script(r"\\b26\NETLOGON\RDP-login-monitor\Deploy-LoginMonitor.ps1")
|
||||
assert r"\\b26\NETLOGON\RDP-login-monitor\Deploy-LoginMonitor.ps1" in script
|
||||
assert "Test-Path -LiteralPath" in script
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/** Fallback до загрузки /health; при релизе держите в sync с backend/app/version.py */
|
||||
export const APP_NAME = "Security Alert Center";
|
||||
export const APP_VERSION = "0.20.11";
|
||||
export const APP_VERSION = "0.20.12";
|
||||
export const APP_VERSION_LABEL = `${APP_NAME} v.${APP_VERSION}`;
|
||||
|
||||
Reference in New Issue
Block a user