Files
RouterOS/RouterOSAssistant/Core/Models/VlanEntry.swift
T
KayandClaude Sonnet 5 8a5df3338a M25: Einrichten-Wizard-Politur + SSH-Trust-Persistenz endlich verifiziert
- WAN-Schritt: fehlenden "Zurück"-Button ergänzt (beide Modi)
- "Abbrechen"/"Jetzt sichern" prominent gemacht (wie "Neu scannen")
- LAN-/VLAN-Schritt: Adressfelder starten leer, nur Format-Beispiel im
  Feld sichtbar statt vorbelegter Werte. VlanStepView bekam dafür eine
  Validierungssperre auf "Weiter" (fehlte bisher, war ok solange
  Defaults immer gültig waren). Zwei Tests entsprechend angepasst.
- SSH-Host-Key-Trust aus M24 hatte sich entgegen der Live-Bestätigung
  nie tatsächlich persistiert (defaults read zeigte leeren Schlüssel,
  Ursache ungeklärt) — betraf BackupServices dedizierte SSH-Verbindung
  beim ersten Experte-Tab-Schreibversuch pro Sitzung. Erneut über den
  bestehenden Trust-Dialog bestätigt, diesmal per defaults read
  verifiziert statt nur der UI-Bestätigung vertraut.

Alles live bestätigt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 12:41:47 +02:00

65 lines
2.8 KiB
Swift

import Foundation
/// One additional virtual network: a VLAN interface on top of an existing (typically LAN
/// bridge) interface, with its own IP range and DHCP server — e.g. a guest or IoT network.
/// Deliberately not port-based (no access/trunk assignment): that needs RouterOS bridge
/// VLAN filtering, which requires "set" operations our REST/SSH command model doesn't
/// support yet (it only ever creates new items). Someone who needs a VLAN on a specific
/// switch port still has to configure that port as a tagged trunk manually.
struct VlanEntry: Identifiable, Equatable {
var id = UUID()
var name: String
var vlanID: Int
var parentInterface: String
var networkAddress: String
var routerAddress: String
var poolRangeStart: String
var poolRangeEnd: String
var leaseTimeHours: Int = 24
var dnsServers: String
/// Blocks forward traffic to/from every other configured LAN/VLAN network — see
/// `FirewallConfig.NetworkSegment`. Internet access (WAN NAT) is unaffected.
var isolated: Bool = false
/// Fields start empty on purpose (Nutzerwunsch: "die auszufüllenden Felder leer lassen,
/// nur Beispiele zeigen ... so sieht man das Schema dahinter") — each TextField's label
/// (e.g. "Router-Adresse (z.B. 192.168.20.1/24)") doubles as its placeholder while empty,
/// so leaving these blank shows the format example instead of hiding it behind an
/// auto-derived value the user might not even notice, let alone check. `VlanStepView`'s
/// "Weiter" button is disabled until every VLAN's fields are actually filled in.
init(name: String = "Gäste", vlanID: Int, parentInterface: String) {
self.name = name
self.vlanID = vlanID
self.parentInterface = parentInterface
self.networkAddress = ""
self.routerAddress = ""
self.poolRangeStart = ""
self.poolRangeEnd = ""
self.dnsServers = ""
}
var interfaceName: String { "vlan\(vlanID)" }
func buildCommands() -> [RouterOSCommand] {
let createVlan = RouterOSCommand.add(
menuPath: "/interface vlan",
restPath: "interface/vlan",
arguments: ["name": interfaceName, "vlan-id": "\(vlanID)", "interface": parentInterface],
summary: "VLAN \"\(name)\" (ID \(vlanID)) auf \(parentInterface) anlegen"
)
let dhcpCommands = DhcpServerCommandBuilder.buildCommands(
interfaceName: interfaceName,
routerAddress: routerAddress,
networkAddress: networkAddress,
poolRangeStart: poolRangeStart,
poolRangeEnd: poolRangeEnd,
leaseTimeHours: leaseTimeHours,
dnsServers: dnsServers,
context: "für VLAN \"\(name)\""
)
return [createVlan] + dhcpCommands
}
}