32 lines
1.6 KiB
TypeScript
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
|
|
}
|