feat(mcp): подготовить сервер и доступ к приёмке

This commit is contained in:
Denozordec committed 2026-11-03 03:12:03 +07:00
commit bf3d50e1ff
3835 files changed
+537122

No files matched your search

+11
View File
@@ -0,0 +1,11 @@
export function fmtBgpNum(n: number | null): string {
if (n === null) return "—"
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`
if (n >= 1_000) return `${(n / 1_000).toFixed(0)}k`
return String(n)
}
export function sumBgpCounters(values: (number | null)[]): number | null {
return values.some(n => n === null) ? null : values.reduce<number>((sum, n) => sum + (n ?? 0), 0)
}
+24
View File
@@ -0,0 +1,24 @@
import { z } from "zod"
import { vxlanServersSchema } from "@/lib/vxlan-response"
const counter = z.number().int().nonnegative()
const autonomousSystem = z.number().int().min(1).max(4294967295).nullable()
export const bgpSessionSchema = z.object({
id: z.string().trim().min(1), serverId: z.number().int().positive(),
serverName: z.string(), serverSite: z.string(), serverCountry: z.string(),
name: z.string(), peerIp: z.string(), remoteAs: autonomousSystem, localAs: autonomousSystem,
localId: z.string(), remoteId: z.string(), state: z.string().trim().min(1), type: z.enum(["eBGP", "iBGP", "Unknown"]),
uptime: z.string().nullable(), holdTime: counter.nullable(), keepalive: counter.nullable(),
prefixesRx: counter.nullable(), prefixesTx: counter.nullable(), inputMessages: counter.nullable(), outputMessages: counter.nullable(),
afi: z.string().nullable().optional(),
capabilities: z.array(z.string()), lastError: z.string().nullable(),
})
export const bgpCatalogSchema = z.object({
sessions: z.array(bgpSessionSchema),
failures: z.array(z.object({ serverId: z.number().int().positive(), serverName: z.string(), error: z.string() })),
}).refine(data => new Set(data.sessions.map(s => JSON.stringify([s.serverId, s.id]))).size === data.sessions.length
&& new Set(data.failures.map(f => f.serverId)).size === data.failures.length
&& !data.sessions.some(s => data.failures.some(f => f.serverId === s.serverId)))
export const bgpServersSchema = vxlanServersSchema
export type BackendBgpSession = z.infer<typeof bgpSessionSchema>
export type BgpFailure = z.infer<typeof bgpCatalogSchema>["failures"][number]
+38
View File
@@ -0,0 +1,38 @@
export type BgpState = "Established" | "Active" | "Idle" | "Connect" | "OpenSent" | "OpenConfirm" | "Unknown"
export type BgpType = "eBGP" | "iBGP" | "Unknown"
export type BgpAfi = "IPv4 Unicast" | "IPv6 Unicast" | "VPNv4 Unicast"
export interface BgpSessionRow {
id: string
serverId: string
serverLabel: string
serverSite: string
peerIp: string
remoteAs: number | null
localAs: number | null
routerId: string
description: string
state: BgpState
type: BgpType
afi: string
uptime: string | null
holdTime: number | null
keepalive: number | null
prefixesRx: number | null
prefixesTx: number | null
prefixesActive: number | null
inputMessages: number | null
outputMessages: number | null
capabilities: string[]
lastError: string | null
}
export const BGP_AS_NAMES: Record<number, string> = {
8359: "МТС / Tele2",
13238: "Яндекс",
12389: "Ростелеком",
24940: "Hetzner",
6777: "AMS-IX",
1299: "Telia",
65001: "iBGP internal",
}