fix: inline git test feedback and use form URLs (0.20.1)

Show git check result next to the button, scroll into view, and test unsaved repo URLs from the form.
This commit is contained in:
2026-06-20 16:29:48 +10:00
parent f411d8f070
commit 07b97bd111
7 changed files with 130 additions and 21 deletions
+16
View File
@@ -1,3 +1,5 @@
from dataclasses import replace
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException
@@ -582,6 +584,12 @@ class AgentUpdateSettingsUpdate(BaseModel):
git_branch: str | None = None
class AgentGitTestRequest(BaseModel):
rdp_git_repo_url: str | None = None
ssh_git_repo_url: str | None = None
git_branch: str | None = None
class AgentGitTestResponse(BaseModel):
git_latest_rdp_version: str | None = None
git_latest_ssh_version: str | None = None
@@ -661,10 +669,18 @@ def update_agent_update_settings(
@router.post("/agent-updates/test-git", response_model=AgentGitTestResponse)
def test_agent_git_release(
body: AgentGitTestRequest | None = None,
db: Session = Depends(get_db),
_user=Depends(require_admin),
) -> AgentGitTestResponse:
cfg = get_effective_agent_update_config(db)
if body is not None:
cfg = replace(
cfg,
rdp_git_repo_url=(body.rdp_git_repo_url or cfg.rdp_git_repo_url).strip(),
ssh_git_repo_url=(body.ssh_git_repo_url or cfg.ssh_git_repo_url).strip(),
git_branch=(body.git_branch or cfg.git_branch or "main").strip() or "main",
)
git_release = get_git_release_versions(cfg, db=db, force_refresh=True)
from app.services.agent_update_settings import PRODUCT_RDP, PRODUCT_SSH
+1 -1
View File
@@ -1,5 +1,5 @@
"""Единый источник версии SAC (API, health, логи, OpenAPI)."""
APP_NAME = "Security Alert Center"
APP_VERSION = "0.20.0"
APP_VERSION = "0.20.1"
APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}"
+2 -2
View File
@@ -4,6 +4,6 @@ from app.version import APP_NAME, APP_VERSION, APP_VERSION_LABEL
def test_version_constants():
assert APP_VERSION == "0.20.0"
assert APP_VERSION == "0.20.1"
assert APP_NAME == "Security Alert Center"
assert APP_VERSION_LABEL == "Security Alert Center v.0.20.0"
assert APP_VERSION_LABEL == "Security Alert Center v.0.20.1"
+8 -1
View File
@@ -581,9 +581,16 @@ export function saveAgentUpdateSettings(
});
}
export function testAgentGitRelease(): Promise<AgentGitTestResult> {
export interface AgentGitTestPayload {
rdp_git_repo_url?: string | null;
ssh_git_repo_url?: string | null;
git_branch?: string | null;
}
export function testAgentGitRelease(payload?: AgentGitTestPayload): Promise<AgentGitTestResult> {
return apiFetch<AgentGitTestResult>("/api/v1/settings/agent-updates/test-git", {
method: "POST",
body: JSON.stringify(payload ?? {}),
});
}
+1 -1
View File
@@ -1,4 +1,4 @@
/** Fallback до загрузки /health; при релизе держите в sync с backend/app/version.py */
export const APP_NAME = "Security Alert Center";
export const APP_VERSION = "0.20.0";
export const APP_VERSION = "0.20.1";
export const APP_VERSION_LABEL = `${APP_NAME} v.${APP_VERSION}`;
+74 -9
View File
@@ -165,7 +165,11 @@
Git-ветка
<input v-model="agentUpdateForm.git_branch" type="text" placeholder="main" />
</label>
<p v-if="agentUpdateLoaded?.git_latest_rdp_version || agentUpdateLoaded?.git_latest_ssh_version" class="settings-meta">
<div ref="agentGitResultRef" class="settings-agent-git-panel">
<p v-if="agentGitFeedback" :class="['settings-agent-git-feedback', agentGitFeedback.kind]">
{{ agentGitFeedback.text }}
</p>
<p v-if="agentGitShowVersions" class="settings-meta settings-agent-git-versions">
Latest из git:
RDP <code>{{ agentUpdateLoaded?.git_latest_rdp_version ?? "—" }}</code>,
SSH <code>{{ agentUpdateLoaded?.git_latest_ssh_version ?? "—" }}</code>
@@ -173,7 +177,8 @@
· обновлено {{ formatDateTime(agentUpdateLoaded.git_fetched_at) }}
</span>
</p>
<p v-if="agentGitTestErrors" class="settings-error-inline">{{ agentGitTestErrors }}</p>
<p v-if="agentGitTestErrors" class="settings-agent-git-feedback error">{{ agentGitTestErrors }}</p>
</div>
<label class="settings-field">
WinRM: путь к Deploy-LoginMonitor.ps1 (fallback)
<input
@@ -580,7 +585,7 @@
</template>
<script setup lang="ts">
import { computed, onMounted, reactive, ref } from "vue";
import { computed, nextTick, onMounted, reactive, ref } from "vue";
import {
apiFetch,
createMobileEnrollmentCode,
@@ -687,6 +692,9 @@ const savingLinuxAdmin = ref(false);
const savingAgentUpdate = ref(false);
const testingAgentGit = ref(false);
const agentGitTestErrors = ref("");
const agentGitShowVersions = ref(false);
const agentGitResultRef = ref<HTMLElement | null>(null);
const agentGitFeedback = ref<{ kind: "success" | "error" | "info"; text: string } | null>(null);
const savingTelegram = ref(false);
const savingWebhook = ref(false);
const savingEmail = ref(false);
@@ -1021,14 +1029,22 @@ async function loadAgentUpdateSettings() {
agentUpdateForm.git_branch = data.git_branch ?? "main";
agentUpdateForm.win_agent_update_script = data.win_agent_update_script ?? "";
agentGitTestErrors.value = Object.values(data.git_errors ?? {}).join("; ");
agentGitShowVersions.value = Boolean(
data.git_latest_rdp_version || data.git_latest_ssh_version || agentGitTestErrors.value,
);
}
async function runAgentGitTest() {
testingAgentGit.value = true;
agentGitTestErrors.value = "";
error.value = "";
agentGitFeedback.value = { kind: "info", text: "Проверка git…" };
agentGitShowVersions.value = true;
try {
const result = await testAgentGitRelease();
const result = await testAgentGitRelease({
rdp_git_repo_url: agentUpdateForm.rdp_git_repo_url.trim() || null,
ssh_git_repo_url: agentUpdateForm.ssh_git_repo_url.trim() || null,
git_branch: agentUpdateForm.git_branch.trim() || "main",
});
if (agentUpdateLoaded.value) {
agentUpdateLoaded.value = {
...agentUpdateLoaded.value,
@@ -1040,11 +1056,31 @@ async function runAgentGitTest() {
}
const errs = Object.values(result.git_errors ?? {});
agentGitTestErrors.value = errs.length ? errs.join("; ") : "";
success.value = result.from_cache
? "Версии из кэша (git не менялся)."
: "Версии успешно прочитаны из git.";
if (errs.length) {
agentGitFeedback.value = {
kind: "error",
text: "Git недоступен или версии не найдены — см. детали ниже.",
};
} else {
const rdp = result.git_latest_rdp_version ?? "—";
const ssh = result.git_latest_ssh_version ?? "—";
agentGitFeedback.value = {
kind: "success",
text: result.from_cache
? `Версии из кэша: RDP ${rdp}, SSH ${ssh}.`
: `Версии прочитаны из git: RDP ${rdp}, SSH ${ssh}.`,
};
}
await nextTick();
agentGitResultRef.value?.scrollIntoView({ behavior: "smooth", block: "nearest" });
} catch (e) {
error.value = e instanceof Error ? e.message : "Ошибка проверки git";
agentGitFeedback.value = {
kind: "error",
text: e instanceof Error ? e.message : "Ошибка проверки git",
};
agentGitTestErrors.value = agentGitFeedback.value.text;
await nextTick();
agentGitResultRef.value?.scrollIntoView({ behavior: "smooth", block: "nearest" });
} finally {
testingAgentGit.value = false;
}
@@ -1481,6 +1517,35 @@ onMounted(() => {
margin: 0;
}
.settings-agent-git-panel {
margin: 0.75rem 0;
padding: 0.75rem 0.85rem;
border: 1px solid #2a3441;
border-radius: 6px;
background: #141a22;
}
.settings-agent-git-feedback {
margin: 0 0 0.5rem;
font-size: 0.92rem;
}
.settings-agent-git-feedback.success {
color: #6dd196;
}
.settings-agent-git-feedback.error {
color: #e87272;
}
.settings-agent-git-feedback.info {
color: #9aa4b2;
}
.settings-agent-git-versions {
margin: 0;
}
.success {
color: #6dd196;
}
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env python3
import sys
sys.path.insert(0, "/opt/security-alert-center/backend")
from app.database import SessionLocal
from app.services.agent_update_settings import get_effective_agent_update_config
from app.services.agent_git_release import get_git_release_versions
db = SessionLocal()
try:
cfg = get_effective_agent_update_config(db)
print("cfg rdp:", cfg.rdp_git_repo_url)
print("cfg ssh:", cfg.ssh_git_repo_url)
print("cfg branch:", cfg.git_branch)
r = get_git_release_versions(cfg, db=db, force_refresh=True)
print("versions:", r.versions)
print("errors:", r.errors)
print("from_cache:", r.from_cache)
print("fetched_at:", r.fetched_at)
finally:
db.close()