From fc161506e7578c12c65e4bde689f626af437652b Mon Sep 17 00:00:00 2001 From: Denozordec Date: Sun, 6 Sep 2026 19:35:01 +0700 Subject: [PATCH] feat(users): enhance interface type mapping and parsing logic Updated the mapRosInterfaceType function to support additional interface types, including "gre-tunnel" and improved handling for various input formats. Enhanced the parseRawInterfaces function to accommodate new interface types in the test cases, ensuring accurate parsing and type assignment. Added corresponding test cases to validate the new functionality and ensure robustness in interface type handling. --- backend/src/modules/users/iface-type.test.ts | 13 +++++++++++-- backend/src/modules/users/iface-type.ts | 14 ++++++++++---- backend/src/modules/users/service/users-service.ts | 2 +- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/backend/src/modules/users/iface-type.test.ts b/backend/src/modules/users/iface-type.test.ts index 1222c43..a455a46 100644 --- a/backend/src/modules/users/iface-type.test.ts +++ b/backend/src/modules/users/iface-type.test.ts @@ -4,23 +4,32 @@ import { mapRosInterfaceType, parseRawInterfaces, isUniqueConstraintError } from assert.equal(mapRosInterfaceType("ether"), "ether") assert.equal(mapRosInterfaceType("ethernet"), "ether") assert.equal(mapRosInterfaceType("GRE"), "gre") +assert.equal(mapRosInterfaceType("gre-tunnel"), "gre") +assert.equal(mapRosInterfaceType("gre6-tunnel"), "gre") assert.equal(mapRosInterfaceType("wg"), "wg") assert.equal(mapRosInterfaceType("wireguard"), "wg") assert.equal(mapRosInterfaceType("vlan"), "other") assert.equal(mapRosInterfaceType(""), "other") +assert.equal(mapRosInterfaceType("", "gre-tunnel1"), "gre") +assert.equal(mapRosInterfaceType("", "MSK-DC"), "other") +assert.equal(mapRosInterfaceType("gre-tunnel", "MSK-DC"), "gre") +assert.equal(mapRosInterfaceType("", "wg-msk-spb"), "wg") +assert.equal(mapRosInterfaceType("", "ether1"), "ether") const parsed = parseRawInterfaces(JSON.stringify([ { name: "ether1", type: "ether", running: "true", disabled: "false" }, - { name: "gre-office", type: "gre", running: "false", disabled: "false" }, + { name: "gre-office", type: "gre-tunnel", running: "false", disabled: "false" }, { name: "wg-msk", type: "wg", running: true, disabled: false }, + { name: "MSK-DC", type: "gre-tunnel", running: true, disabled: false }, { name: "", type: "ether" }, ])) -assert.equal(parsed.length, 3) +assert.equal(parsed.length, 4) assert.equal(parsed[0]?.type, "ether") assert.equal(parsed[0]?.running, true) assert.equal(parsed[1]?.type, "gre") assert.equal(parsed[1]?.running, false) assert.equal(parsed[2]?.type, "wg") +assert.equal(parsed[3]?.type, "gre") assert.equal(parseRawInterfaces("not-json").length, 0) assert.equal(parseRawInterfaces(null).length, 0) diff --git a/backend/src/modules/users/iface-type.ts b/backend/src/modules/users/iface-type.ts index 64feec9..b920857 100644 --- a/backend/src/modules/users/iface-type.ts +++ b/backend/src/modules/users/iface-type.ts @@ -1,10 +1,16 @@ export type InterfaceType = "ether" | "gre" | "wg" | "other" -export function mapRosInterfaceType(raw: string | undefined | null): InterfaceType { +export function mapRosInterfaceType(raw: string | undefined | null, name?: string): InterfaceType { const t = String(raw ?? "").trim().toLowerCase() - if (t === "ether" || t === "ethernet") return "ether" - if (t === "gre") return "gre" + if (t === "ether" || t === "ethernet" || t.startsWith("ether")) return "ether" + // RouterOS /interface type for GRE is "gre-tunnel" (also gre, gre6, gre6-tunnel) + if (t === "gre" || t.startsWith("gre-") || t.startsWith("gre6")) return "gre" if (t === "wg" || t === "wireguard") return "wg" + + const n = String(name ?? "").trim().toLowerCase() + if (n.startsWith("gre") || n.includes("gre-tunnel")) return "gre" + if (n.startsWith("wg-") || n.startsWith("wireguard")) return "wg" + if (n.startsWith("ether") || n.startsWith("sfp")) return "ether" return "other" } @@ -34,7 +40,7 @@ export function parseRawInterfaces(json: string | null | undefined): ParsedRosIf if (!name) continue out.push({ name, - type: mapRosInterfaceType(String(rec.type ?? "")), + type: mapRosInterfaceType(String(rec.type ?? ""), name), running: asBool(rec.running), disabled: asBool(rec.disabled), }) diff --git a/backend/src/modules/users/service/users-service.ts b/backend/src/modules/users/service/users-service.ts index 61d2006..9ff396a 100644 --- a/backend/src/modules/users/service/users-service.ts +++ b/backend/src/modules/users/service/users-service.ts @@ -252,7 +252,7 @@ export function listInterfaceCatalog(serverId: number): CatalogInterface[] { seen.add(r.interfaceName) ifaces.push({ name: r.interfaceName, - type: mapRosInterfaceType(""), + type: mapRosInterfaceType("", r.interfaceName), running: Boolean(r.running), disabled: Boolean(r.disabled), })