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 datetime import datetime
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
@@ -582,6 +584,12 @@ class AgentUpdateSettingsUpdate(BaseModel):
|
|||||||
git_branch: str | None = None
|
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):
|
class AgentGitTestResponse(BaseModel):
|
||||||
git_latest_rdp_version: str | None = None
|
git_latest_rdp_version: str | None = None
|
||||||
git_latest_ssh_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)
|
@router.post("/agent-updates/test-git", response_model=AgentGitTestResponse)
|
||||||
def test_agent_git_release(
|
def test_agent_git_release(
|
||||||
|
body: AgentGitTestRequest | None = None,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
_user=Depends(require_admin),
|
_user=Depends(require_admin),
|
||||||
) -> AgentGitTestResponse:
|
) -> AgentGitTestResponse:
|
||||||
cfg = get_effective_agent_update_config(db)
|
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)
|
git_release = get_git_release_versions(cfg, db=db, force_refresh=True)
|
||||||
from app.services.agent_update_settings import PRODUCT_RDP, PRODUCT_SSH
|
from app.services.agent_update_settings import PRODUCT_RDP, PRODUCT_SSH
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
"""Единый источник версии SAC (API, health, логи, OpenAPI)."""
|
"""Единый источник версии SAC (API, health, логи, OpenAPI)."""
|
||||||
|
|
||||||
APP_NAME = "Security Alert Center"
|
APP_NAME = "Security Alert Center"
|
||||||
APP_VERSION = "0.20.0"
|
APP_VERSION = "0.20.1"
|
||||||
APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}"
|
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():
|
def test_version_constants():
|
||||||
assert APP_VERSION == "0.20.0"
|
assert APP_VERSION == "0.20.1"
|
||||||
assert APP_NAME == "Security Alert Center"
|
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", {
|
return apiFetch<AgentGitTestResult>("/api/v1/settings/agent-updates/test-git", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
body: JSON.stringify(payload ?? {}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/** Fallback до загрузки /health; при релизе держите в sync с backend/app/version.py */
|
/** Fallback до загрузки /health; при релизе держите в sync с backend/app/version.py */
|
||||||
export const APP_NAME = "Security Alert Center";
|
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}`;
|
export const APP_VERSION_LABEL = `${APP_NAME} v.${APP_VERSION}`;
|
||||||
|
|||||||
@@ -165,7 +165,11 @@
|
|||||||
Git-ветка
|
Git-ветка
|
||||||
<input v-model="agentUpdateForm.git_branch" type="text" placeholder="main" />
|
<input v-model="agentUpdateForm.git_branch" type="text" placeholder="main" />
|
||||||
</label>
|
</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:
|
Latest из git:
|
||||||
RDP <code>{{ agentUpdateLoaded?.git_latest_rdp_version ?? "—" }}</code>,
|
RDP <code>{{ agentUpdateLoaded?.git_latest_rdp_version ?? "—" }}</code>,
|
||||||
SSH <code>{{ agentUpdateLoaded?.git_latest_ssh_version ?? "—" }}</code>
|
SSH <code>{{ agentUpdateLoaded?.git_latest_ssh_version ?? "—" }}</code>
|
||||||
@@ -173,7 +177,8 @@
|
|||||||
· обновлено {{ formatDateTime(agentUpdateLoaded.git_fetched_at) }}
|
· обновлено {{ formatDateTime(agentUpdateLoaded.git_fetched_at) }}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</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">
|
<label class="settings-field">
|
||||||
WinRM: путь к Deploy-LoginMonitor.ps1 (fallback)
|
WinRM: путь к Deploy-LoginMonitor.ps1 (fallback)
|
||||||
<input
|
<input
|
||||||
@@ -580,7 +585,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, reactive, ref } from "vue";
|
import { computed, nextTick, onMounted, reactive, ref } from "vue";
|
||||||
import {
|
import {
|
||||||
apiFetch,
|
apiFetch,
|
||||||
createMobileEnrollmentCode,
|
createMobileEnrollmentCode,
|
||||||
@@ -687,6 +692,9 @@ const savingLinuxAdmin = ref(false);
|
|||||||
const savingAgentUpdate = ref(false);
|
const savingAgentUpdate = ref(false);
|
||||||
const testingAgentGit = ref(false);
|
const testingAgentGit = ref(false);
|
||||||
const agentGitTestErrors = ref("");
|
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 savingTelegram = ref(false);
|
||||||
const savingWebhook = ref(false);
|
const savingWebhook = ref(false);
|
||||||
const savingEmail = ref(false);
|
const savingEmail = ref(false);
|
||||||
@@ -1021,14 +1029,22 @@ async function loadAgentUpdateSettings() {
|
|||||||
agentUpdateForm.git_branch = data.git_branch ?? "main";
|
agentUpdateForm.git_branch = data.git_branch ?? "main";
|
||||||
agentUpdateForm.win_agent_update_script = data.win_agent_update_script ?? "";
|
agentUpdateForm.win_agent_update_script = data.win_agent_update_script ?? "";
|
||||||
agentGitTestErrors.value = Object.values(data.git_errors ?? {}).join("; ");
|
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() {
|
async function runAgentGitTest() {
|
||||||
testingAgentGit.value = true;
|
testingAgentGit.value = true;
|
||||||
agentGitTestErrors.value = "";
|
agentGitTestErrors.value = "";
|
||||||
error.value = "";
|
agentGitFeedback.value = { kind: "info", text: "Проверка git…" };
|
||||||
|
agentGitShowVersions.value = true;
|
||||||
try {
|
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) {
|
if (agentUpdateLoaded.value) {
|
||||||
agentUpdateLoaded.value = {
|
agentUpdateLoaded.value = {
|
||||||
...agentUpdateLoaded.value,
|
...agentUpdateLoaded.value,
|
||||||
@@ -1040,11 +1056,31 @@ async function runAgentGitTest() {
|
|||||||
}
|
}
|
||||||
const errs = Object.values(result.git_errors ?? {});
|
const errs = Object.values(result.git_errors ?? {});
|
||||||
agentGitTestErrors.value = errs.length ? errs.join("; ") : "";
|
agentGitTestErrors.value = errs.length ? errs.join("; ") : "";
|
||||||
success.value = result.from_cache
|
if (errs.length) {
|
||||||
? "Версии из кэша (git не менялся)."
|
agentGitFeedback.value = {
|
||||||
: "Версии успешно прочитаны из git.";
|
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) {
|
} 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 {
|
} finally {
|
||||||
testingAgentGit.value = false;
|
testingAgentGit.value = false;
|
||||||
}
|
}
|
||||||
@@ -1481,6 +1517,35 @@ onMounted(() => {
|
|||||||
margin: 0;
|
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 {
|
.success {
|
||||||
color: #6dd196;
|
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