fix(netflow): проверять ответы аналитики и выбранный месяц
This commit is contained in:
1 parent
979dc3cfb0
commit
64df472202
10 files changed
+271
-16
No files matched your search
@@ -12,13 +12,21 @@ import type {
|
||||
TrafficFlowSettingsPatch,
|
||||
} from "@mmapp/contracts/traffic-flow"
|
||||
import { z } from "zod"
|
||||
import { trafficFlowSettingsDtoSchema, trafficFlowSettingsPatchSchema, trafficFlowHostFileSchema, flowPurgeDtoSchema } from "@mmapp/contracts/traffic-flow"
|
||||
import { trafficFlowSettingsDtoSchema, trafficFlowSettingsPatchSchema, trafficFlowHostFileSchema, flowPurgeDtoSchema, flowAnalyticsDtoSchema, flowMonthlyDtoSchema } from "@mmapp/contracts/traffic-flow"
|
||||
import { requestJson } from "@/shared/api/http-client"
|
||||
|
||||
export type { TrafficFlowHostFile }
|
||||
|
||||
const flowSettingsSchema = trafficFlowSettingsDtoSchema.extend({ flowListenPort: z.number().int().min(1).max(65535), wgListenPort: z.number().int().min(1).max(65535) }).refine(data => (!data.hasHostPrivateKey || data.hostPublicKey.length > 0) && (!data.listenerBound || !!data.listenerAddress) && (data.lastDatagramAt === null || Number.isFinite(Date.parse(data.lastDatagramAt))) && new Set(data.peers.map(peer => peer.serverId)).size === data.peers.length, "Несогласованные настройки NetFlow")
|
||||
const flowPatchSchema = trafficFlowSettingsPatchSchema.strict()
|
||||
// Optional overlay/wire measurements may be unavailable independently of the
|
||||
// confirmed primary counters. Preserve that distinction instead of inventing zero.
|
||||
const optionalFlowMetric = z.preprocess(value => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : undefined, z.number().nonnegative().optional())
|
||||
const flowAnalyticsSchema = flowAnalyticsDtoSchema.extend({
|
||||
bytesPayload: optionalFlowMetric, bytesOverlay: optionalFlowMetric,
|
||||
bytesMesh: optionalFlowMetric, bytesWire: optionalFlowMetric,
|
||||
bpsOverlay: optionalFlowMetric, bpsWire: optionalFlowMetric,
|
||||
}).refine(data => [...data.rxSeries, ...data.txSeries].every(value => Number.isFinite(value) && value >= 0), "Некорректные измерения трафика")
|
||||
function flowConfirmed<T>(schema: z.ZodType<T>, raw: unknown): T {
|
||||
const parsed = schema.safeParse(raw)
|
||||
if (!parsed.success) throw new Error("Данные NetFlow не подтверждены: получен некорректный ответ сервера")
|
||||
@@ -135,7 +143,7 @@ export async function getFlowAnalytics(
|
||||
excludeOverlay?: boolean
|
||||
},
|
||||
): Promise<FlowAnalyticsDto> {
|
||||
return requestJson<FlowAnalyticsDto>(baseUrl, `/api/traffic/flow/analytics${flowQuery(params)}`)
|
||||
return flowConfirmed(flowAnalyticsSchema, await requestJson<unknown>(baseUrl, `/api/traffic/flow/analytics${flowQuery(params)}`))
|
||||
}
|
||||
|
||||
export async function getFlowMonthly(
|
||||
@@ -145,7 +153,9 @@ export async function getFlowMonthly(
|
||||
const q = new URLSearchParams()
|
||||
q.set("month", params.month)
|
||||
if (params.serverId) q.set("serverId", params.serverId)
|
||||
return requestJson<FlowMonthlyDto>(baseUrl, `/api/traffic/flow/monthly?${q.toString()}`)
|
||||
const data = flowConfirmed(flowMonthlyDtoSchema, await requestJson<unknown>(baseUrl, `/api/traffic/flow/monthly?${q.toString()}`))
|
||||
if (data.month !== params.month) throw new Error("Сервер вернул данные другого месяца. Повторите загрузку.")
|
||||
return data
|
||||
}
|
||||
|
||||
export async function purgeTrafficFlowData(baseUrl: string, init?: RequestInit): Promise<FlowPurgeDto> {
|
||||
|
||||
Reference in new issue
Block a user