feat(mcp): подготовить сервер и доступ к приёмке
This commit is contained in:
commit
bf3d50e1ff
3835 files changed
+537122
No files matched your search
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* Снимок прогона планировщика (JSON из `scheduler_runs.result_json`).
|
||||
* Дублирует контракт `backend/src/types/scheduler-run-snapshot.ts` для UI.
|
||||
*/
|
||||
|
||||
export interface ServerRestPingSnapshot {
|
||||
serverId: number
|
||||
name: string
|
||||
host: string
|
||||
ok: boolean
|
||||
latencyMs?: number | null
|
||||
error?: string
|
||||
}
|
||||
|
||||
export interface ServersRestPingRunSnapshot {
|
||||
v: number
|
||||
job: "servers_rest_ping"
|
||||
sampledAt: string
|
||||
skipped?: boolean
|
||||
fatalError?: string
|
||||
servers: ServerRestPingSnapshot[]
|
||||
}
|
||||
|
||||
export type AlertEngineRuleDiagSnapshot = {
|
||||
ruleId: string
|
||||
inGroup: boolean
|
||||
evalHit: boolean
|
||||
hitTransition?: "problem" | "recovery" | "neutral"
|
||||
hitMessage?: string
|
||||
stabilityOk: boolean
|
||||
cooldownOk: boolean
|
||||
telegramOk: boolean
|
||||
blocked?:
|
||||
| "no_hit"
|
||||
| "stability"
|
||||
| "cooldown"
|
||||
| "no_telegram"
|
||||
| "dedupe_positive"
|
||||
| "in_group"
|
||||
}
|
||||
|
||||
/** Сводка прогона движка оповещений (JSON из `scheduler_runs` для job `alert_engine`). */
|
||||
export interface AlertEngineRunSnapshot {
|
||||
v: number
|
||||
job: "alert_engine"
|
||||
sampledAt: string
|
||||
rulesChecked: number
|
||||
standaloneFires: number
|
||||
groupFires: number
|
||||
skippedNoTelegram: boolean
|
||||
errors?: string[]
|
||||
ruleDiag?: AlertEngineRuleDiagSnapshot[]
|
||||
}
|
||||
|
||||
export interface GreBgpSnapshotRunSnapshot {
|
||||
v: number
|
||||
job: "gre_bgp"
|
||||
sampledAt: string
|
||||
skipped?: boolean
|
||||
fatalError?: string
|
||||
greWritten: number
|
||||
bgpWritten: number
|
||||
errors?: string[]
|
||||
}
|
||||
|
||||
export interface InternetPathRunSnapshot {
|
||||
v: number
|
||||
job: "internet_path"
|
||||
sampledAt: string
|
||||
homes: number
|
||||
snapshotSaved: boolean
|
||||
fatalError?: string
|
||||
}
|
||||
|
||||
export interface CertificatesRenewRunSnapshot {
|
||||
v: number
|
||||
job: "certificates_renew"
|
||||
sampledAt: string
|
||||
skipped?: boolean
|
||||
fatalError?: string
|
||||
checked: number
|
||||
renewed: number
|
||||
skippedTargets: number
|
||||
errors: string[]
|
||||
}
|
||||
|
||||
export interface BackupsRunSnapshot {
|
||||
v: number
|
||||
job: "backups"
|
||||
sampledAt: string
|
||||
skipped?: boolean
|
||||
due: boolean
|
||||
created: number
|
||||
failures: number
|
||||
pruned: number
|
||||
uploadFailures?: number
|
||||
pruneFailures?: number
|
||||
metadataError?: string
|
||||
eventErrors?: string[]
|
||||
errors?: string[]
|
||||
fatalError?: string
|
||||
}
|
||||
|
||||
export interface GeoipUpdateRunSnapshot {
|
||||
v: number
|
||||
job: "geoip_update"
|
||||
sampledAt: string
|
||||
skipped?: boolean
|
||||
fatalError?: string
|
||||
checked: number
|
||||
downloaded: number
|
||||
skippedUnchanged: number
|
||||
bytes: number
|
||||
errors: string[]
|
||||
}
|
||||
|
||||
export interface RouterLogsRunSnapshot {
|
||||
v: 1
|
||||
job: "router_logs"
|
||||
sampledAt: string
|
||||
skipped?: boolean
|
||||
errors: string[]
|
||||
servers: { serverId: number; name: string; added: number; gap: boolean; error?: string }[]
|
||||
}
|
||||
export type SchedulerRunSnapshot =
|
||||
| RouterLogsRunSnapshot
|
||||
| TrafficRunSnapshot
|
||||
| ResourcesRunSnapshot
|
||||
| PingRunSnapshot
|
||||
| SpeedScheduledRunSnapshot
|
||||
| ServersRestPingRunSnapshot
|
||||
| GreBgpSnapshotRunSnapshot
|
||||
| InternetPathRunSnapshot
|
||||
| CertificatesRenewRunSnapshot
|
||||
| BackupsRunSnapshot
|
||||
| GeoipUpdateRunSnapshot
|
||||
| AlertEngineRunSnapshot
|
||||
|
||||
export interface TrafficServerSnapshot {
|
||||
serverId: number
|
||||
name: string
|
||||
host: string
|
||||
ok: boolean
|
||||
error?: string
|
||||
interfaces?: number
|
||||
sumRxMbps?: number
|
||||
sumTxMbps?: number
|
||||
}
|
||||
|
||||
export interface TrafficRunSnapshot {
|
||||
v: number
|
||||
job: "traffic"
|
||||
sampledAt: string
|
||||
skipped?: boolean
|
||||
fatalError?: string
|
||||
servers: TrafficServerSnapshot[]
|
||||
}
|
||||
|
||||
export interface ResourceServerSnapshot {
|
||||
serverId: number
|
||||
name: string
|
||||
host: string
|
||||
status: "online" | "offline"
|
||||
error?: string
|
||||
cpuLoadPct?: number
|
||||
memUsedMb?: number
|
||||
memTotalMb?: number
|
||||
memUsedPct?: number
|
||||
diskFreeMb?: number
|
||||
diskTotalMb?: number
|
||||
uptimeSeconds?: number
|
||||
boardName?: string
|
||||
rosVersion?: string
|
||||
}
|
||||
|
||||
export interface ResourcesRunSnapshot {
|
||||
v: number
|
||||
job: "uptime_resources"
|
||||
sampledAt: string
|
||||
skipped?: boolean
|
||||
fatalError?: string
|
||||
servers: ResourceServerSnapshot[]
|
||||
}
|
||||
|
||||
export interface PingProbeSnapshot {
|
||||
probeId: string
|
||||
name: string
|
||||
target: string
|
||||
srcServerId: number
|
||||
srcServerName: string
|
||||
srcInterface: string
|
||||
ok: boolean
|
||||
rttMs: number | null
|
||||
lossPct: number | null
|
||||
status: "up" | "warn" | "down" | "unknown"
|
||||
error?: string
|
||||
}
|
||||
|
||||
export interface PingRunSnapshot {
|
||||
v: number
|
||||
job: "uptime_ping"
|
||||
sampledAt: string
|
||||
skipped?: boolean
|
||||
fatalError?: string
|
||||
probes: PingProbeSnapshot[]
|
||||
skippedByInterval?: number
|
||||
}
|
||||
|
||||
export interface SpeedRunSnapshot {
|
||||
probeId: string
|
||||
srcServerId: number
|
||||
srcServerName: string
|
||||
dstServerId: number
|
||||
dstServerName: string
|
||||
srcInterface: string
|
||||
dstInterface: string
|
||||
protocol: string
|
||||
direction: string
|
||||
durationSec: number
|
||||
ok: boolean
|
||||
txAvgMbps?: number | null
|
||||
rxAvgMbps?: number | null
|
||||
pingRttMs?: number | null
|
||||
pingLossPct?: number | null
|
||||
pingError?: string | null
|
||||
error?: string
|
||||
}
|
||||
|
||||
export interface SpeedScheduledRunSnapshot {
|
||||
v: number
|
||||
job: "uptime_speed"
|
||||
sampledAt: string
|
||||
runs: SpeedRunSnapshot[]
|
||||
}
|
||||
|
||||
/** PostgreSQL JSONB returns an object; older records may still contain JSON text. */
|
||||
export function parseSchedulerRunSnapshot(raw: unknown): SchedulerRunSnapshot | null {
|
||||
try {
|
||||
const value: unknown = typeof raw === "string" ? (raw.trim() ? JSON.parse(raw) : null) : raw
|
||||
if (!value || typeof value !== "object" || Array.isArray(value)) return null
|
||||
const o = value as Record<string, unknown>
|
||||
if (o.v !== 1 || typeof o.job !== "string" || typeof o.sampledAt !== "string" || !Number.isFinite(Date.parse(o.sampledAt))) return null
|
||||
if (o.skipped !== undefined && typeof o.skipped !== "boolean") return null
|
||||
if (o.fatalError !== undefined && typeof o.fatalError !== "string") return null
|
||||
for (const field of ["errors", "eventErrors"]) if (o[field] !== undefined && (!Array.isArray(o[field]) || !(o[field] as unknown[]).every(error => typeof error === "string"))) return null
|
||||
const arrays: Record<string, string> = { router_logs: "servers", traffic: "servers", uptime_resources: "servers", servers_rest_ping: "servers", uptime_ping: "probes", uptime_speed: "runs" }
|
||||
if (Object.hasOwn(arrays, o.job)) {
|
||||
if (!Array.isArray(o[arrays[o.job]])) return null
|
||||
} else {
|
||||
const fields: Record<string, string[]> = { gre_bgp: ["greWritten", "bgpWritten"], internet_path: ["homes"], certificates_renew: ["checked", "renewed", "skippedTargets"], backups: ["created", "failures", "pruned"], geoip_update: ["checked", "downloaded", "skippedUnchanged", "bytes"], alert_engine: ["rulesChecked", "standaloneFires", "groupFires"] }
|
||||
if (!Object.hasOwn(fields, o.job) || !fields[o.job].every(field => typeof o[field] === "number" && Number.isSafeInteger(o[field]) && (o[field] as number) >= 0)) return null
|
||||
if (["certificates_renew", "geoip_update"].includes(o.job) && !Array.isArray(o.errors)) return null
|
||||
if (o.job === "backups") {
|
||||
if (typeof o.due !== "boolean") return null
|
||||
for (const field of ["uploadFailures", "pruneFailures"]) if (o[field] !== undefined && (typeof o[field] !== "number" || !Number.isSafeInteger(o[field]) || (o[field] as number) < 0)) return null
|
||||
if (o.metadataError !== undefined && typeof o.metadataError !== "string") return null
|
||||
}
|
||||
if (o.job === "internet_path" && typeof o.snapshotSaved !== "boolean") return null
|
||||
if (o.job === "alert_engine" && typeof o.skippedNoTelegram !== "boolean") return null
|
||||
}
|
||||
return o as unknown as SchedulerRunSnapshot
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user