32 lines
1.8 KiB
TypeScript
32 lines
1.8 KiB
TypeScript
import type { Server, VxlanTunnel } from "./data"
|
|
|
|
/** RouterOS string literals: https://help.mikrotik.com/docs/spaces/ROS/pages/47579229/Scripting */
|
|
export function quoteRosString(value: string): string {
|
|
return '"' + value.replace(/[\\"$\x00-\x1f\x7f]/g, char => {
|
|
if (char === "\\" || char === '"' || char === "$") return "\\" + char
|
|
return "\\" + char.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")
|
|
}) + '"'
|
|
}
|
|
|
|
const commentLine = (value: string) => value.replace(/[\r\n\x00-\x1f\x7f]/g, " ")
|
|
|
|
/** A configuration fragment, not a full RouterOS export: bridge/FDB are not available in this API. */
|
|
export function generateVxlanRsc(t: VxlanTunnel, servers: Record<string, Server>): string {
|
|
const server = servers[t.serverId]
|
|
const lines = [`# VXLAN — ${commentLine(t.name)} · VNI ${t.vni}`]
|
|
if (server) lines.push(`# Сервер: ${commentLine(server.name)} (${commentLine(server.host)})`)
|
|
lines.push("# RouterOS 7.x · интерфейс и статические VTEP; IP-адреса, bridge/FDB не включены", "")
|
|
const args = [
|
|
`name=${quoteRosString(t.name)}`, `vni=${t.vni}`, `port=${t.dstPort}`,
|
|
`arp=${quoteRosString(t.arpMode ?? (t.arpProxy ? "proxy-arp" : "enabled"))}`,
|
|
`learning=${t.macLearning ? "yes" : "no"}`, `disabled=${t.enabled ? "no" : "yes"}`,
|
|
`comment=${quoteRosString(t.comment)}`,
|
|
]
|
|
if (t.vtepIp) args.push(`local-address=${quoteRosString(t.vtepIp)}`)
|
|
if (t.mtu !== undefined) args.push(`mtu=${t.mtu}`)
|
|
else lines.push("# MTU в снимке отсутствует: проверьте его перед применением")
|
|
lines.push("/interface/vxlan/add " + args.join(" "))
|
|
for (const remote of t.remoteVteps) lines.push(`/interface/vxlan/vteps/add interface=${quoteRosString(t.name)} remote-ip=${quoteRosString(remote)}`)
|
|
return lines.join("\n") + "\n"
|
|
}
|