fix(ui): показывать ошибки и свежесть NetFlow карты
This commit is contained in:
1 parent
e47e2b4029
commit
1bce4e1ea2
7 files changed
+139
-45
No files matched your search
@@ -13,3 +13,19 @@ test("network map refuses partial GRE and foreign failure/probe contexts",()=>{
|
||||
const probe={id:"p",srcServerId:"1",dstServerId:"2",srcInterface:"",dstInterface:"",enabled:true,lastTxAvgMbps:null,lastRxAvgMbps:null,lastPingRttMs:null,lastPingLossPct:null,lastPingAt:null}
|
||||
assert.throws(()=>validateNetworkMapSnapshot([server],{tunnels:[]},{probes:[probe]}),/неизвестному/)
|
||||
})
|
||||
|
||||
import {networkMapFlowSchema,validateNetworkMapDns} from "./network-map-response"
|
||||
test("map Flow envelope retains zeros and refuses missing metadata and contradictory totals",()=>{
|
||||
const empty={"hops":[],"live":false,"rangeMinutes":5,"windowSec":300,"totalBytes":0,"namedBytes":0,"unclassifiedBytes":0,"asnLoaded":false,"countryLoaded":false,"services":[],"serviceEdges":[],"servicePaths":[],"countries":[],"countryEdges":[],"countryPaths":[],"countryServiceGroups":[],"mapServiceMinSharePct":5,"dedupApplied":false,"excludeMeshApplied":false,"excludeOverlayApplied":false}
|
||||
assert.equal(networkMapFlowSchema.parse(empty).totalBytes,0)
|
||||
assert.equal(networkMapFlowSchema.parse(empty).live,false)
|
||||
assert.throws(()=>networkMapFlowSchema.parse({...empty,totalBytes:undefined}))
|
||||
assert.throws(()=>networkMapFlowSchema.parse({...empty,namedBytes:1}))
|
||||
assert.throws(()=>networkMapFlowSchema.parse({...empty,rangeMinutes:10}))
|
||||
})
|
||||
test("map DNS matches exactly requested names and accepts explicit unresolved null",()=>{
|
||||
assert.deepEqual(validateNetworkMapDns({results:{"router.example":null}},["router.example"]),{"router.example":null})
|
||||
assert.throws(()=>validateNetworkMapDns({results:{}},["router.example"]))
|
||||
assert.throws(()=>validateNetworkMapDns({results:{"foreign.example":"192.0.2.1"}},["router.example"]))
|
||||
assert.throws(()=>validateNetworkMapDns({results:{"router.example":"not-ip"}},["router.example"]))
|
||||
})
|
||||
@@ -18,3 +18,13 @@ export function validateNetworkMapSnapshot(servers:unknown,gre:unknown,probes:un
|
||||
if(tunnels.failures.length)throw new Error("Неполный каталог GRE: "+tunnels.failures.map(failure=>failure.serverName||failure.serverId).join(", "))
|
||||
return {servers:inventory,tunnels:tunnels.tunnels,probes:measurements.probes}
|
||||
}
|
||||
|
||||
import {flowMapHopsDtoSchema} from "@mmapp/contracts/traffic-flow"
|
||||
import {isIpv4String} from "./gre-endpoint-resolve"
|
||||
export const networkMapFlowSchema=flowMapHopsDtoSchema.required().refine(data=>data.rangeMinutes===5&&data.namedBytes<=data.totalBytes&&data.unclassifiedBytes<=data.totalBytes)
|
||||
export function validateNetworkMapDns(raw:unknown,hosts:string[]){
|
||||
const data=z.object({results:z.record(z.string(),z.string().refine(isIpv4String).nullable())}).parse(raw)
|
||||
const requested=new Set(hosts.map(host=>host.toLowerCase()))
|
||||
if(Object.keys(data.results).length!==requested.size||Object.keys(data.results).some(host=>!requested.has(host)))throw new Error("DNS-ответ не соответствует запрошенным именам")
|
||||
return data.results
|
||||
}
|
||||
Reference in new issue
Block a user