Files
MikrotikManager/backend/src/services/ospf-optimizer-identity.ts
T

32 lines
1.6 KiB
TypeScript

import {z} from "zod"
import {observedBoolean} from "./ospf-observed-values.js"
const schema=z.array(z.object({"router-id":z.string().optional(),disabled:z.string().optional()}))
function literal(value:string|undefined){
const id=value?.trim(),parts=id?.split(".")
return id && id!=="0.0.0.0" && parts?.length===4 && parts.every(part=>/^(0|[1-9]\d{0,2})$/.test(part)&&Number(part)<=255)?id:null
}
export async function resolveOptimizerRouterOwners(devices:readonly {id:number}[],needed:Set<string>,read:(id:number)=>Promise<unknown>):Promise<Map<string,number>>{
if(needed.size===0)return new Map()
const owners=new Map<string,Set<number>>()
for(const device of devices){
let raw:unknown
try {raw=await read(device.id)} catch {throw new Error("Не удалось проверить Router ID устройства "+device.id)}
const parsed=schema.safeParse(raw)
if(!parsed.success)throw new Error("Недостоверный каталог OSPF устройства "+device.id)
for(const instance of parsed.data){
const disabled=observedBoolean(instance.disabled)
if(disabled===true)continue
const id=literal(instance["router-id"])
if(disabled===null||id===null)throw new Error("Неизвестен Router ID или disabled устройства "+device.id)
const set=owners.get(id)??new Set<number>();set.add(device.id);owners.set(id,set)
}
}
const result=new Map<string,number>()
for(const id of needed){
const set=owners.get(id)
if(set && set.size>1)throw new Error("Router ID "+id+" принадлежит нескольким устройствам")
if(set?.size===1)result.set(id,[...set][0])
}
return result
}