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:
@@ -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,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}"
|
||||
|
||||
@@ -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
@@ -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,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}`;
|
||||
|
||||
@@ -165,15 +165,20 @@
|
||||
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">
|
||||
Latest из git:
|
||||
RDP <code>{{ agentUpdateLoaded?.git_latest_rdp_version ?? "—" }}</code>,
|
||||
SSH <code>{{ agentUpdateLoaded?.git_latest_ssh_version ?? "—" }}</code>
|
||||
<span v-if="agentUpdateLoaded?.git_fetched_at">
|
||||
· обновлено {{ formatDateTime(agentUpdateLoaded.git_fetched_at) }}
|
||||
</span>
|
||||
</p>
|
||||
<p v-if="agentGitTestErrors" class="settings-error-inline">{{ agentGitTestErrors }}</p>
|
||||
<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>
|
||||
<span v-if="agentUpdateLoaded?.git_fetched_at">
|
||||
· обновлено {{ formatDateTime(agentUpdateLoaded.git_fetched_at) }}
|
||||
</span>
|
||||
</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;
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user