feat(frontend): git agent versions plate on Hosts list (0.20.32)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -27,7 +27,11 @@ from app.services.host_remote_actions import (
|
||||
run_ssh_monitor_update_action,
|
||||
start_host_remote_action,
|
||||
)
|
||||
from app.services.agent_update_settings import get_effective_agent_update_config
|
||||
from app.services.agent_update_settings import (
|
||||
PRODUCT_RDP,
|
||||
PRODUCT_SSH,
|
||||
get_effective_agent_update_config,
|
||||
)
|
||||
from app.services.agent_host_config import get_host_agent_settings, update_host_agent_config
|
||||
from app.services.host_sessions import (
|
||||
HostSessionRow,
|
||||
@@ -165,6 +169,8 @@ def list_hosts(
|
||||
page_size=page_size,
|
||||
latest_agent_versions=latest_map,
|
||||
reference_agent_versions=reference_map,
|
||||
git_latest_rdp_version=git_release.versions.get(PRODUCT_RDP) or None,
|
||||
git_latest_ssh_version=git_release.versions.get(PRODUCT_SSH) or None,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -53,6 +53,14 @@ class HostListResponse(BaseModel):
|
||||
default_factory=dict,
|
||||
description="Эталон для «устарела»: max(git latest, min, max в fleet)",
|
||||
)
|
||||
git_latest_rdp_version: str | None = Field(
|
||||
None,
|
||||
description="Последняя версия rdp-login-monitor из git (version.txt / main)",
|
||||
)
|
||||
git_latest_ssh_version: str | None = Field(
|
||||
None,
|
||||
description="Последняя версия ssh-monitor из git (version.txt / main)",
|
||||
)
|
||||
|
||||
|
||||
class EventSummary(BaseModel):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""Единый источник версии SAC (API, health, логи, OpenAPI)."""
|
||||
|
||||
APP_NAME = "Security Alert Center"
|
||||
APP_VERSION = "0.20.31"
|
||||
APP_VERSION = "0.20.32"
|
||||
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.31"
|
||||
assert APP_VERSION == "0.20.32"
|
||||
assert APP_NAME == "Security Alert Center"
|
||||
assert APP_VERSION_LABEL == "Security Alert Center v.0.20.31"
|
||||
assert APP_VERSION_LABEL == "Security Alert Center v.0.20.32"
|
||||
|
||||
@@ -286,6 +286,9 @@ export interface HostListResponse {
|
||||
latest_agent_versions?: Record<string, string>;
|
||||
/** Эталон для «устарела»: max(git latest, min, max в fleet) */
|
||||
reference_agent_versions?: Record<string, string>;
|
||||
/** Последние версии из git (version.txt на main) */
|
||||
git_latest_rdp_version?: string | null;
|
||||
git_latest_ssh_version?: string | null;
|
||||
}
|
||||
|
||||
export interface ProblemSummary {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/** Fallback до загрузки /health; при релизе держите в sync с backend/app/version.py */
|
||||
export const APP_NAME = "Security Alert Center";
|
||||
export const APP_VERSION = "0.20.31";
|
||||
export const APP_VERSION = "0.20.32";
|
||||
export const APP_VERSION_LABEL = `${APP_NAME} v.${APP_VERSION}`;
|
||||
|
||||
@@ -19,10 +19,24 @@
|
||||
<p v-if="error" class="error">{{ error }}</p>
|
||||
<p v-else-if="loading">Загрузка…</p>
|
||||
<template v-else>
|
||||
<p>
|
||||
<div class="hosts-list-meta">
|
||||
<p class="hosts-list-total">
|
||||
Всего: {{ data?.total ?? 0 }}
|
||||
<span v-if="live" class="live-badge">live</span>
|
||||
</p>
|
||||
<aside
|
||||
class="agent-releases-plate"
|
||||
title="Версии из git-репозиториев агентов (version.txt, ветка main)"
|
||||
>
|
||||
<span class="agent-releases-plate__label">Последние версии агентов:</span>
|
||||
<span class="agent-releases-plate__item">
|
||||
Win: <code>{{ gitWinVersion }}</code>
|
||||
</span>
|
||||
<span class="agent-releases-plate__item">
|
||||
SSH: <code>{{ gitSshVersion }}</code>
|
||||
</span>
|
||||
</aside>
|
||||
</div>
|
||||
<table class="hosts-table">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -242,6 +256,13 @@ function setSort(key: SortKey) {
|
||||
saveHostsSortPrefs(sortBy.value, sortDir.value);
|
||||
}
|
||||
|
||||
const gitWinVersion = computed(
|
||||
() => data.value?.git_latest_rdp_version?.trim() || "—",
|
||||
);
|
||||
const gitSshVersion = computed(
|
||||
() => data.value?.git_latest_ssh_version?.trim() || "—",
|
||||
);
|
||||
|
||||
function sortMark(key: SortKey) {
|
||||
if (sortBy.value !== key) return "";
|
||||
return sortDir.value === "asc" ? "↑" : "↓";
|
||||
@@ -412,3 +433,53 @@ watch(
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hosts-list-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
gap: 0.5rem 0.75rem;
|
||||
margin: 0.35rem 0 1rem;
|
||||
}
|
||||
|
||||
.hosts-list-total {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.agent-releases-plate {
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
gap: 0.35rem 0.85rem;
|
||||
margin: -0.15rem 0 0;
|
||||
padding: 0.45rem 1rem 0.5rem 1.1rem;
|
||||
border-radius: 0 0.75rem 0.75rem 0.35rem;
|
||||
border: 1px solid #2d3a4d;
|
||||
border-left: 3px solid #58a6ff;
|
||||
background: linear-gradient(135deg, #1a2332 0%, #151d28 100%);
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 0, 0, 0.35),
|
||||
0 1px 0 rgba(88, 166, 255, 0.12) inset;
|
||||
font-size: 0.9rem;
|
||||
color: #9aa4b2;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.agent-releases-plate__label {
|
||||
color: #c9d1d9;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.agent-releases-plate__item code {
|
||||
font-size: 0.88em;
|
||||
color: #79c0ff;
|
||||
background: rgba(88, 166, 255, 0.08);
|
||||
padding: 0.1rem 0.35rem;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user