Experte-Tab: ausführlichere Tooltips, Sektions-Überschrift, aktive Auswahl hervorgehoben
Alle RouterOSFieldSchema.help-Texte in RouterOSSchemaCatalog.swift überarbeitet — jedes Adress-/Netz-/Bereichs-Feld hat jetzt ein konkretes Beispiel (z.B. 192.168.88.1/24), vorher leere Hilfetexte gefüllt. Zusätzlich zwei UI-Wünsche umgesetzt: fette Überschrift (Menüname + Kategorie) im Detailbereich, da vorher unklar war, in welcher Sektion man sich befindet; und hellblaue Hervorhebung des aktiven Eintrags in der linken Liste (per Zeileninhalt-Hintergrund statt .listRowBackground, das vom macOS-Sidebar-Stil überschrieben wird). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDmUd93KxsYGr2kLTotWnG
This commit is contained in:
+16
-7
@@ -896,13 +896,22 @@ beim Ändern die RouterOS-Suffix-Form zurück) — angewendet auf DHCP-Server
|
||||
(weder Exception noch im Output-Text) — bei einer leer bleibenden
|
||||
Liste in Übersicht/Geräte/Experte-Tab als erste Verdachtsquelle
|
||||
prüfen.
|
||||
10. **Offener Nutzerwunsch, noch nicht umgesetzt:** ausführlichere
|
||||
Tooltips im Experte-Tab für alle Sektionen, mit konkretem
|
||||
Adress-Format-Beispiel (z.B. "10.10.10.1/24") statt nur "mit
|
||||
Präfix". Viele `RouterOSFieldSchema.help`-Texte in
|
||||
`RouterOSSchemaCatalog.swift` sind aktuell leer (`help: ""`) oder
|
||||
knapp ohne Beispielwert — wurde diese Session zugunsten des
|
||||
M8-Hardware-Tests zurückgestellt.
|
||||
10. ~~Ausführlichere Tooltips im Experte-Tab~~ — erledigt: alle
|
||||
`RouterOSFieldSchema.help`-Texte in `RouterOSSchemaCatalog.swift`
|
||||
überarbeitet, jedes Adress-/Netz-/Bereichs-Feld hat jetzt ein
|
||||
konkretes Beispiel (z.B. "192.168.88.1/24" oder
|
||||
"192.168.88.10-192.168.88.254"), vorher leere `help: ""`-Texte
|
||||
gefüllt (u.a. bei Mangle/Raw-Regeln, den meisten "Deaktiviert"-
|
||||
Feldern, WireGuard-Peer-Feldern, System-/Tool-Menüs). Dabei zwei
|
||||
weitere Nutzerwünsche ergänzt: eine fette Überschrift (Menüname +
|
||||
Kategorie) oben in `ExpertMenuDetailView`, da vorher nicht erkennbar
|
||||
war, in welcher Sektion man sich befindet; und eine hellblaue
|
||||
Hervorhebung des gerade geöffneten Eintrags in der linken Liste
|
||||
(`ExpertView`) — dafür `.listRowBackground` auf macOS' Sidebar-Stil
|
||||
verworfen (wird vom System überschrieben/nicht sichtbar), stattdessen
|
||||
Hintergrund direkt am Zeileninhalt (`Text` in `RoundedRectangle`-
|
||||
Fill) gesetzt. Alles vom Nutzer live in Xcode bestätigt ("passt
|
||||
gut").
|
||||
|
||||
Gitea-Remote `origin` ist eingerichtet und wird laufend gepusht (siehe
|
||||
oben) — dieser Hinweis war veraltet, korrigiert am 2026-09-15.
|
||||
|
||||
@@ -29,7 +29,7 @@ enum RouterOSSchemaCatalog {
|
||||
warning: "Reihenfolge zählt. Neue Regeln landen am Ende der Liste — eine bereits vorhandene, weiter oben stehende Regel kann eine neue Regel unerreichbar machen. Position danach mit \"/ip firewall filter print\" kontrollieren, notfalls mit \"move\" verschieben.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "chain", label: "Chain", kind: .text,
|
||||
help: "input = an den Router, forward = durch den Router, output = vom Router aus. Eigene Chains (Sprungziele über \"jump\") sind ebenfalls möglich.",
|
||||
help: "input = an den Router, forward = durch den Router, output = vom Router aus. Eigene Chains (Sprungziele über \"jump\") sind ebenfalls möglich. Beispiel: forward",
|
||||
defaultValue: "forward", required: true),
|
||||
RouterOSFieldSchema(key: "action", label: "Aktion", kind: .enumPick(options: [
|
||||
"accept", "drop", "reject", "log", "jump", "return",
|
||||
@@ -37,9 +37,9 @@ enum RouterOSSchemaCatalog {
|
||||
]), help: "Was mit passenden Paketen geschieht. reject schickt zusätzlich eine Fehlermeldung zurück, drop verwirft stillschweigend.",
|
||||
defaultValue: "accept", required: true),
|
||||
RouterOSFieldSchema(key: "src-address", label: "Quell-Adresse", kind: .text,
|
||||
help: "Einzel-IP oder Netz (z.B. 192.168.88.0/24). Leer = beliebig."),
|
||||
help: "Einzel-IP oder Netz mit Präfix, z.B. 192.168.88.5 oder 192.168.88.0/24. Leer = beliebig."),
|
||||
RouterOSFieldSchema(key: "dst-address", label: "Ziel-Adresse", kind: .text,
|
||||
help: "Einzel-IP oder Netz. Leer = beliebig."),
|
||||
help: "Einzel-IP oder Netz mit Präfix, z.B. 192.168.88.5 oder 192.168.88.0/24. Leer = beliebig."),
|
||||
RouterOSFieldSchema(key: "src-address-list", label: "Quelle in Adress-Liste",
|
||||
kind: .menuItemPick(menuPath: "/ip firewall address-list", restPath: "ip/firewall/address-list", valueField: "list"),
|
||||
help: "Nur Pakete, deren Absender in dieser zuvor angelegten Adress-Liste steht."),
|
||||
@@ -47,14 +47,14 @@ enum RouterOSSchemaCatalog {
|
||||
kind: .menuItemPick(menuPath: "/ip firewall address-list", restPath: "ip/firewall/address-list", valueField: "list"),
|
||||
help: "Nur Pakete, deren Ziel in dieser zuvor angelegten Adress-Liste steht."),
|
||||
RouterOSFieldSchema(key: "in-interface", label: "Eingangs-Interface", kind: .interfacePick,
|
||||
help: "Nur Pakete, die über dieses Interface hereinkommen."),
|
||||
help: "Nur Pakete, die über dieses Interface hereinkommen, z.B. ether1 oder bridge."),
|
||||
RouterOSFieldSchema(key: "out-interface", label: "Ausgangs-Interface", kind: .interfacePick,
|
||||
help: "Nur Pakete, die über dieses Interface hinausgehen."),
|
||||
help: "Nur Pakete, die über dieses Interface hinausgehen, z.B. ether1 oder bridge."),
|
||||
RouterOSFieldSchema(key: "protocol", label: "Protokoll", kind: .enumPick(options: [
|
||||
"tcp", "udp", "icmp", "gre", "ipsec-esp", "ipsec-ah"
|
||||
]), help: "IP-Protokoll. Leer = alle."),
|
||||
RouterOSFieldSchema(key: "dst-port", label: "Ziel-Port(s)", kind: .text,
|
||||
help: "Nur bei tcp/udp sinnvoll. Einzelner Port (80) oder Bereich (8000-8100)."),
|
||||
help: "Nur bei tcp/udp sinnvoll. Einzelner Port (z.B. 80) oder Bereich (z.B. 8000-8100)."),
|
||||
RouterOSFieldSchema(key: "connection-state", label: "Verbindungsstatus", kind: .enumPick(options: [
|
||||
"new", "established", "related", "invalid", "untracked"
|
||||
]), help: "Status laut Connection-Tracking. \"established,related\" ist die übliche \"schon erlaubte Verbindung\"-Regel."),
|
||||
@@ -83,18 +83,20 @@ enum RouterOSSchemaCatalog {
|
||||
"masquerade", "src-nat", "dst-nat", "netmap", "redirect", "same"
|
||||
]), help: "masquerade = automatisches NAT über die aktuelle WAN-IP (empfohlen bei wechselnder IP). src-nat = feste NAT-Adresse. dst-nat = Ziel umschreiben (Portweiterleitung). redirect = auf den Router selbst umlenken.",
|
||||
defaultValue: "masquerade", required: true),
|
||||
RouterOSFieldSchema(key: "src-address", label: "Quell-Adresse", kind: .text, help: "Leer = beliebig."),
|
||||
RouterOSFieldSchema(key: "dst-address", label: "Ziel-Adresse", kind: .text, help: "Leer = beliebig."),
|
||||
RouterOSFieldSchema(key: "src-address", label: "Quell-Adresse", kind: .text,
|
||||
help: "Einzel-IP oder Netz mit Präfix, z.B. 192.168.88.0/24. Leer = beliebig."),
|
||||
RouterOSFieldSchema(key: "dst-address", label: "Ziel-Adresse", kind: .text,
|
||||
help: "Einzel-IP oder Netz mit Präfix, z.B. 192.168.88.0/24. Leer = beliebig."),
|
||||
RouterOSFieldSchema(key: "in-interface", label: "Eingangs-Interface", kind: .interfacePick,
|
||||
help: "Bei dstnat meist der WAN-Port (woher die Anfrage aus dem Internet kommt)."),
|
||||
help: "Bei dstnat meist der WAN-Port (woher die Anfrage aus dem Internet kommt), z.B. ether1."),
|
||||
RouterOSFieldSchema(key: "out-interface", label: "Ausgangs-Interface", kind: .interfacePick,
|
||||
help: "Bei srcnat/masquerade meist der WAN-Port."),
|
||||
help: "Bei srcnat/masquerade meist der WAN-Port, z.B. ether1."),
|
||||
RouterOSFieldSchema(key: "protocol", label: "Protokoll", kind: .enumPick(options: ["tcp", "udp", "icmp"]),
|
||||
help: "Nötig, damit Ports geprüft werden können."),
|
||||
RouterOSFieldSchema(key: "dst-port", label: "Ziel-Port der Anfrage", kind: .text,
|
||||
help: "Der Port, auf den die Anfrage von außen ankommt (z.B. 8080)."),
|
||||
help: "Der Port, auf den die Anfrage von außen ankommt, z.B. 8080."),
|
||||
RouterOSFieldSchema(key: "to-addresses", label: "Weiterleiten an (interne IP)", kind: .text,
|
||||
help: "Nur bei dst-nat: die interne IP-Adresse, an die weitergeleitet wird."),
|
||||
help: "Nur bei dst-nat: die interne IP-Adresse, an die weitergeleitet wird, z.B. 192.168.88.10."),
|
||||
RouterOSFieldSchema(key: "to-ports", label: "Weiterleiten an (interner Port)", kind: .text,
|
||||
help: "Nur bei dst-nat: interner Port, falls abweichend vom Ziel-Port (z.B. extern 8080 → intern 80)."),
|
||||
RouterOSFieldSchema(key: "comment", label: "Kommentar", kind: .text, help: "Nur zur Wiedererkennung."),
|
||||
@@ -125,14 +127,21 @@ enum RouterOSSchemaCatalog {
|
||||
help: "Frei wählbarer Name für die Paketmarkierung."),
|
||||
RouterOSFieldSchema(key: "passthrough", label: "Weitere Mangle-Regeln noch prüfen", kind: .bool,
|
||||
help: "Ja (Standard) lässt nachfolgende Mangle-Regeln diese Verbindung noch zusätzlich prüfen.", defaultValue: "yes"),
|
||||
RouterOSFieldSchema(key: "src-address", label: "Quell-Adresse", kind: .text, help: "Leer = beliebig."),
|
||||
RouterOSFieldSchema(key: "dst-address", label: "Ziel-Adresse", kind: .text, help: "Leer = beliebig."),
|
||||
RouterOSFieldSchema(key: "in-interface", label: "Eingangs-Interface", kind: .interfacePick, help: ""),
|
||||
RouterOSFieldSchema(key: "out-interface", label: "Ausgangs-Interface", kind: .interfacePick, help: ""),
|
||||
RouterOSFieldSchema(key: "protocol", label: "Protokoll", kind: .enumPick(options: ["tcp", "udp", "icmp"]), help: ""),
|
||||
RouterOSFieldSchema(key: "dst-port", label: "Ziel-Port(s)", kind: .text, help: "Nur bei tcp/udp."),
|
||||
RouterOSFieldSchema(key: "src-address", label: "Quell-Adresse", kind: .text,
|
||||
help: "Einzel-IP oder Netz mit Präfix, z.B. 192.168.88.0/24. Leer = beliebig."),
|
||||
RouterOSFieldSchema(key: "dst-address", label: "Ziel-Adresse", kind: .text,
|
||||
help: "Einzel-IP oder Netz mit Präfix, z.B. 192.168.88.0/24. Leer = beliebig."),
|
||||
RouterOSFieldSchema(key: "in-interface", label: "Eingangs-Interface", kind: .interfacePick,
|
||||
help: "Nur Pakete, die über dieses Interface hereinkommen, z.B. ether1 oder bridge."),
|
||||
RouterOSFieldSchema(key: "out-interface", label: "Ausgangs-Interface", kind: .interfacePick,
|
||||
help: "Nur Pakete, die über dieses Interface hinausgehen, z.B. ether1 oder bridge."),
|
||||
RouterOSFieldSchema(key: "protocol", label: "Protokoll", kind: .enumPick(options: ["tcp", "udp", "icmp"]),
|
||||
help: "IP-Protokoll. Leer = alle."),
|
||||
RouterOSFieldSchema(key: "dst-port", label: "Ziel-Port(s)", kind: .text,
|
||||
help: "Nur bei tcp/udp sinnvoll. Einzelner Port (z.B. 80) oder Bereich (z.B. 8000-8100)."),
|
||||
RouterOSFieldSchema(key: "comment", label: "Kommentar", kind: .text, help: "Nur zur Wiedererkennung."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Regel inaktiv schalten, ohne sie zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["chain", "action", "comment"]
|
||||
),
|
||||
@@ -146,17 +155,24 @@ enum RouterOSSchemaCatalog {
|
||||
warning: "notrack nimmt den betroffenen Verkehr aus dem Connection-Tracking heraus — danach greifen dafür keine Filter-/NAT-Regeln mehr, die sich auf connection-state oder NAT verlassen. Nur gezielt einsetzen.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "chain", label: "Chain", kind: .enumPick(options: ["prerouting", "output"]),
|
||||
help: "", defaultValue: "prerouting", required: true),
|
||||
help: "prerouting = eingehende Pakete, bevor der Router sie verarbeitet. output = vom Router selbst erzeugte Pakete.",
|
||||
defaultValue: "prerouting", required: true),
|
||||
RouterOSFieldSchema(key: "action", label: "Aktion", kind: .enumPick(options: ["accept", "drop", "notrack"]),
|
||||
help: "notrack = von der Connection-Tracking-Verfolgung ausnehmen (siehe Warnhinweis oben).",
|
||||
defaultValue: "accept", required: true),
|
||||
RouterOSFieldSchema(key: "src-address", label: "Quell-Adresse", kind: .text, help: ""),
|
||||
RouterOSFieldSchema(key: "dst-address", label: "Ziel-Adresse", kind: .text, help: ""),
|
||||
RouterOSFieldSchema(key: "in-interface", label: "Eingangs-Interface", kind: .interfacePick, help: ""),
|
||||
RouterOSFieldSchema(key: "protocol", label: "Protokoll", kind: .enumPick(options: ["tcp", "udp", "icmp"]), help: ""),
|
||||
RouterOSFieldSchema(key: "dst-port", label: "Ziel-Port(s)", kind: .text, help: ""),
|
||||
RouterOSFieldSchema(key: "comment", label: "Kommentar", kind: .text, help: ""),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
RouterOSFieldSchema(key: "src-address", label: "Quell-Adresse", kind: .text,
|
||||
help: "Einzel-IP oder Netz mit Präfix, z.B. 192.168.88.0/24. Leer = beliebig."),
|
||||
RouterOSFieldSchema(key: "dst-address", label: "Ziel-Adresse", kind: .text,
|
||||
help: "Einzel-IP oder Netz mit Präfix, z.B. 192.168.88.0/24. Leer = beliebig."),
|
||||
RouterOSFieldSchema(key: "in-interface", label: "Eingangs-Interface", kind: .interfacePick,
|
||||
help: "Nur Pakete, die über dieses Interface hereinkommen, z.B. ether1."),
|
||||
RouterOSFieldSchema(key: "protocol", label: "Protokoll", kind: .enumPick(options: ["tcp", "udp", "icmp"]),
|
||||
help: "IP-Protokoll. Leer = alle."),
|
||||
RouterOSFieldSchema(key: "dst-port", label: "Ziel-Port(s)", kind: .text,
|
||||
help: "Nur bei tcp/udp sinnvoll. Einzelner Port (z.B. 80) oder Bereich (z.B. 8000-8100)."),
|
||||
RouterOSFieldSchema(key: "comment", label: "Kommentar", kind: .text, help: "Nur zur eigenen Wiedererkennung."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Regel inaktiv schalten, ohne sie zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["chain", "action", "comment"]
|
||||
),
|
||||
@@ -169,12 +185,12 @@ enum RouterOSSchemaCatalog {
|
||||
explanation: "Statt in jeder Regel einzelne IPs aufzuzählen, legst du hier eine benannte Liste an (z.B. \"gesperrt\" oder \"vertraut\") und verweist in Filter-/NAT-/Mangle-Regeln per \"src-address-list\"/\"dst-address-list\" darauf. Einträge können dauerhaft oder mit Ablaufzeit (timeout) sein.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "list", label: "Listen-Name", kind: .text,
|
||||
help: "Frei wählbarer Name, wird in anderen Regeln referenziert.", required: true),
|
||||
help: "Frei wählbarer Name, wird in anderen Regeln referenziert, z.B. gesperrt.", required: true),
|
||||
RouterOSFieldSchema(key: "address", label: "Adresse", kind: .text,
|
||||
help: "Einzel-IP oder Netz, z.B. 192.168.88.5 oder 10.0.0.0/24.", required: true),
|
||||
help: "Einzel-IP oder Netz mit Präfix, z.B. 192.168.88.5 oder 10.0.0.0/24.", required: true),
|
||||
RouterOSFieldSchema(key: "timeout", label: "Ablaufzeit", kind: .duration,
|
||||
help: "Optional. Nach dieser Zeit wird der Eintrag automatisch entfernt. Alles auf 0 lassen = bleibt dauerhaft, bis manuell entfernt."),
|
||||
RouterOSFieldSchema(key: "comment", label: "Kommentar", kind: .text, help: "")
|
||||
RouterOSFieldSchema(key: "comment", label: "Kommentar", kind: .text, help: "Nur zur eigenen Wiedererkennung.")
|
||||
],
|
||||
listColumns: ["list", "address"]
|
||||
)
|
||||
@@ -192,7 +208,8 @@ enum RouterOSSchemaCatalog {
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar, z.B. bridge-lan.", required: true),
|
||||
RouterOSFieldSchema(key: "vlan-filtering", label: "VLAN-Filterung (802.1Q)", kind: .bool,
|
||||
help: "Aktiviert echte VLAN-Trennung über diese Bridge — nötig, wenn mehrere VLANs über dieselben Bridge-Ports laufen sollen.", defaultValue: "no"),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Bridge inaktiv schalten, ohne sie zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["name"]
|
||||
),
|
||||
@@ -204,9 +221,9 @@ enum RouterOSSchemaCatalog {
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "bridge", label: "Bridge", kind: .text, help: "Name der Bridge, z.B. bridge-lan.", required: true),
|
||||
RouterOSFieldSchema(key: "interface", label: "Physischer Port", kind: .interfacePick,
|
||||
help: "Der Port, der der Bridge hinzugefügt wird.", required: true),
|
||||
help: "Der Port, der der Bridge hinzugefügt wird, z.B. ether2.", required: true),
|
||||
RouterOSFieldSchema(key: "pvid", label: "Port-VLAN-ID (PVID)", kind: .int,
|
||||
help: "Nur mit aktivierter VLAN-Filterung relevant: VLAN, dem untagged ankommender Verkehr an diesem Port zugeordnet wird.")
|
||||
help: "Nur mit aktivierter VLAN-Filterung relevant: VLAN, dem untagged ankommender Verkehr an diesem Port zugeordnet wird, z.B. 20.")
|
||||
],
|
||||
listColumns: ["bridge", "interface"]
|
||||
),
|
||||
@@ -217,10 +234,11 @@ enum RouterOSSchemaCatalog {
|
||||
explanation: "Ein eigenes logisches Netzwerk auf demselben Kabel, unterschieden durch eine VLAN-Kennung im Ethernet-Rahmen.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar, z.B. vlan20-gaeste.", required: true),
|
||||
RouterOSFieldSchema(key: "vlan-id", label: "VLAN-ID", kind: .int, help: "Eindeutige Kennung, 2–4094.", required: true),
|
||||
RouterOSFieldSchema(key: "vlan-id", label: "VLAN-ID", kind: .int, help: "Eindeutige Kennung, 2–4094, z.B. 20.", required: true),
|
||||
RouterOSFieldSchema(key: "interface", label: "Basis-Interface", kind: .interfacePick,
|
||||
help: "Physischer Port oder Bridge, auf dem dieses VLAN aufsetzt.", required: true),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
help: "Physischer Port oder Bridge, auf dem dieses VLAN aufsetzt, z.B. bridge.", required: true),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "VLAN-Interface inaktiv schalten, ohne es zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["name", "vlan-id", "interface"]
|
||||
),
|
||||
@@ -236,7 +254,8 @@ enum RouterOSSchemaCatalog {
|
||||
help: "Port, auf dem dieser Tunnel auf eingehende Verbindungen lauscht, z.B. 51820.", defaultValue: "51820"),
|
||||
RouterOSFieldSchema(key: "private-key", label: "Privater Schlüssel", kind: .text,
|
||||
help: "Geheim halten. Leer lassen, damit RouterOS automatisch einen erzeugt."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Interface inaktiv schalten, ohne es zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["name", "listen-port"]
|
||||
),
|
||||
@@ -249,12 +268,14 @@ enum RouterOSSchemaCatalog {
|
||||
RouterOSFieldSchema(key: "interface", label: "WireGuard-Interface",
|
||||
kind: .menuItemPick(menuPath: "/interface wireguard", restPath: "interface/wireguard", valueField: "name"),
|
||||
help: "Name des zuvor angelegten WireGuard-Interfaces.", required: true),
|
||||
RouterOSFieldSchema(key: "public-key", label: "Öffentlicher Schlüssel der Gegenstelle", kind: .text, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "public-key", label: "Öffentlicher Schlüssel der Gegenstelle", kind: .text,
|
||||
help: "Vom Gerät der Gegenstelle kopieren (z.B. per \"wg show <interface> public-key\").", required: true),
|
||||
RouterOSFieldSchema(key: "allowed-address", label: "Erlaubte Adressen", kind: .text,
|
||||
help: "Welche IP-Adressen/Netze über diesen Peer laufen dürfen, z.B. 10.10.10.2/32."),
|
||||
help: "Welche IP-Adressen/Netze über diesen Peer laufen dürfen, mit Präfix, z.B. 10.10.10.2/32."),
|
||||
RouterOSFieldSchema(key: "endpoint-address", label: "Feste Adresse der Gegenstelle", kind: .text,
|
||||
help: "Nur nötig, wenn diese Gegenstelle selbst erreichbar sein muss (Site-to-Site). Bei Roadwarrior-Clients, die sich selbst melden, leer lassen."),
|
||||
RouterOSFieldSchema(key: "endpoint-port", label: "Port der Gegenstelle", kind: .text, help: ""),
|
||||
help: "Nur nötig, wenn diese Gegenstelle selbst erreichbar sein muss (Site-to-Site), z.B. eine feste öffentliche IP oder ein DNS-Name. Bei Roadwarrior-Clients, die sich selbst melden, leer lassen."),
|
||||
RouterOSFieldSchema(key: "endpoint-port", label: "Port der Gegenstelle", kind: .text,
|
||||
help: "Meist derselbe Port wie der Listen-Port der Gegenstelle, z.B. 51820."),
|
||||
RouterOSFieldSchema(key: "persistent-keepalive", label: "Keepalive (Sekunden)", kind: .text,
|
||||
help: "Z.B. 25 — hält die Verbindung durch NAT/Firewalls am Leben. Wichtig bei Clients hinter NAT.")
|
||||
],
|
||||
@@ -268,10 +289,11 @@ enum RouterOSSchemaCatalog {
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar, z.B. pppoe-wan.", required: true),
|
||||
RouterOSFieldSchema(key: "interface", label: "Physischer Port", kind: .interfacePick,
|
||||
help: "Der Port, über den die Einwahl läuft, meist der WAN-Port.", required: true),
|
||||
help: "Der Port, über den die Einwahl läuft, meist der WAN-Port, z.B. ether1.", required: true),
|
||||
RouterOSFieldSchema(key: "user", label: "Benutzername", kind: .text, help: "Zugangsdaten des Providers.", required: true),
|
||||
RouterOSFieldSchema(key: "password", label: "Passwort", kind: .text, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
RouterOSFieldSchema(key: "password", label: "Passwort", kind: .text, help: "Zugangsdaten des Providers.", required: true),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Einwahl inaktiv schalten, ohne sie zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["name", "interface"]
|
||||
),
|
||||
@@ -281,7 +303,7 @@ enum RouterOSSchemaCatalog {
|
||||
summary: "Bündelt mehrere physische Ports zu einer logischen, ausfalltoleranten/schnelleren Verbindung.",
|
||||
explanation: "",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar.", required: true),
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar, z.B. bond1.", required: true),
|
||||
RouterOSFieldSchema(key: "slaves", label: "Gebündelte Ports", kind: .text,
|
||||
help: "Kommagetrennte Liste physischer Ports, z.B. ether2,ether3."),
|
||||
RouterOSFieldSchema(key: "mode", label: "Modus", kind: .enumPick(options: [
|
||||
@@ -302,9 +324,11 @@ enum RouterOSSchemaCatalog {
|
||||
explanation: "Jede IP-Adresse hängt an genau einem Interface (physischer Port, Bridge oder VLAN).",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "address", label: "Adresse", kind: .text,
|
||||
help: "Mit Präfix, z.B. 192.168.88.1/24.", required: true),
|
||||
RouterOSFieldSchema(key: "interface", label: "Interface", kind: .interfacePick, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
help: "IP-Adresse mit Netzmaske als Präfix (Router-Adresse in diesem Netz), z.B. 192.168.88.1/24 oder 10.10.10.1/24. Das /24 legt fest, wie viele Geräte in dieses Netz passen (/24 = bis zu 254).", required: true),
|
||||
RouterOSFieldSchema(key: "interface", label: "Interface", kind: .interfacePick,
|
||||
help: "Interface, dem diese Adresse zugewiesen wird, z.B. bridge oder ether4.", required: true),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Adresse inaktiv schalten, ohne sie zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["address", "interface"]
|
||||
),
|
||||
@@ -314,9 +338,9 @@ enum RouterOSSchemaCatalog {
|
||||
summary: "Adressbereiche, aus denen DHCP-Server oder PPP-Profile Adressen vergeben.",
|
||||
explanation: "",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar.", required: true),
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar, z.B. dhcp_pool_lan.", required: true),
|
||||
RouterOSFieldSchema(key: "ranges", label: "Bereich(e)", kind: .text,
|
||||
help: "Z.B. 192.168.88.10-192.168.88.254. Mehrere Bereiche kommagetrennt.", required: true)
|
||||
help: "Von-bis-Adresse ohne Präfix, z.B. 192.168.88.10-192.168.88.254. Mehrere Bereiche kommagetrennt.", required: true)
|
||||
],
|
||||
listColumns: ["name", "ranges"]
|
||||
),
|
||||
@@ -326,15 +350,16 @@ enum RouterOSSchemaCatalog {
|
||||
summary: "Vergibt automatisch IP-Adressen an Geräte in einem Netzwerk.",
|
||||
explanation: "Für die üblichen Fälle deckt das bereits der Einrichten-Assistent (LAN-/VLAN-Schritt) ab — hier direkter Zugriff für Sonderfälle.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar.", required: true),
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar, z.B. dhcp_lan.", required: true),
|
||||
RouterOSFieldSchema(key: "interface", label: "Interface", kind: .interfacePick,
|
||||
help: "Netzwerk, in dem dieser Server Adressen vergibt.", required: true),
|
||||
help: "Netzwerk, in dem dieser Server Adressen vergibt, z.B. bridge.", required: true),
|
||||
RouterOSFieldSchema(key: "address-pool", label: "Adress-Pool",
|
||||
kind: .menuItemPick(menuPath: "/ip pool", restPath: "ip/pool", valueField: "name"),
|
||||
help: "Name eines zuvor angelegten Adress-Pools.", required: true),
|
||||
RouterOSFieldSchema(key: "lease-time", label: "Lease-Zeit", kind: .duration,
|
||||
help: "Wie lange ein Gerät seine Adresse behält, bevor sie erneuert werden muss."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
help: "Wie lange ein Gerät seine Adresse behält, bevor sie erneuert werden muss, z.B. 1d oder 12h."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "DHCP-Server inaktiv schalten, ohne ihn zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["name", "interface"]
|
||||
),
|
||||
@@ -345,10 +370,11 @@ enum RouterOSSchemaCatalog {
|
||||
explanation: "Getrennt vom DHCP-Server selbst, weil dieselben Netzwerk-Optionen für mehrere DHCP-Server gelten können.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "address", label: "Netz", kind: .text,
|
||||
help: "Für dieses Netz gelten die folgenden Optionen, z.B. 192.168.88.0/24.", required: true),
|
||||
help: "Für dieses Netz gelten die folgenden Optionen — die Netzadresse mit Präfix, z.B. 192.168.88.0/24.", required: true),
|
||||
RouterOSFieldSchema(key: "gateway", label: "Gateway", kind: .text,
|
||||
help: "In der Regel die Router-Adresse in diesem Netz.", required: true),
|
||||
RouterOSFieldSchema(key: "dns-server", label: "DNS-Server", kind: .text, help: "Meist der Router selbst.")
|
||||
help: "In der Regel die Router-Adresse in diesem Netz, ohne Präfix, z.B. 192.168.88.1.", required: true),
|
||||
RouterOSFieldSchema(key: "dns-server", label: "DNS-Server", kind: .text,
|
||||
help: "Meist der Router selbst, z.B. 192.168.88.1. Mehrere Server kommagetrennt möglich.")
|
||||
],
|
||||
listColumns: ["address", "gateway"]
|
||||
),
|
||||
@@ -359,12 +385,13 @@ enum RouterOSSchemaCatalog {
|
||||
explanation: "",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "interface", label: "Interface", kind: .interfacePick,
|
||||
help: "Meist der WAN-Port.", required: true),
|
||||
help: "Meist der WAN-Port, z.B. ether1.", required: true),
|
||||
RouterOSFieldSchema(key: "add-default-route", label: "Standardroute übernehmen", kind: .bool,
|
||||
help: "Übernimmt die vom Provider mitgeteilte Standardroute ins Internet.", defaultValue: "yes"),
|
||||
RouterOSFieldSchema(key: "use-peer-dns", label: "DNS-Server übernehmen", kind: .bool,
|
||||
help: "Übernimmt die vom Provider mitgeteilten DNS-Server.", defaultValue: "yes"),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "DHCP-Client inaktiv schalten, ohne ihn zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["interface"]
|
||||
),
|
||||
@@ -377,7 +404,7 @@ enum RouterOSSchemaCatalog {
|
||||
RouterOSFieldSchema(key: "servers", label: "DNS-Server", kind: .text,
|
||||
help: "Ein oder mehrere Server, kommagetrennt, z.B. 1.1.1.1,8.8.8.8."),
|
||||
RouterOSFieldSchema(key: "allow-remote-requests", label: "Als DNS-Server fürs LAN erlauben", kind: .bool,
|
||||
help: "Lässt Geräte im LAN den Router selbst als DNS-Server nutzen.", defaultValue: "no")
|
||||
help: "Lässt Geräte im LAN den Router selbst als DNS-Server nutzen. Ohne das schlagen DNS-Anfragen von Geräten an den Router fehl, selbst wenn sie ihn als DNS-Server eingetragen haben.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["servers"],
|
||||
isSingleton: true
|
||||
@@ -392,10 +419,11 @@ enum RouterOSSchemaCatalog {
|
||||
RouterOSFieldSchema(key: "name", label: "Dienst", kind: .enumPick(options: [
|
||||
"www", "www-ssl", "ssh", "api", "api-ssl", "winbox", "ftp", "telnet"
|
||||
]), help: "Welcher Verwaltungsdienst geändert wird.", required: true),
|
||||
RouterOSFieldSchema(key: "port", label: "Port", kind: .int, help: "Auf welchem Port der Dienst lauscht."),
|
||||
RouterOSFieldSchema(key: "port", label: "Port", kind: .int, help: "Auf welchem Port der Dienst lauscht, z.B. 22 für ssh."),
|
||||
RouterOSFieldSchema(key: "available-from", label: "Erlaubt von", kind: .text,
|
||||
help: "Optional: nur von dieser Adresse/diesem Netz aus erreichbar, z.B. 192.168.88.0/24."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
help: "Optional: nur von dieser Adresse/diesem Netz aus erreichbar, mit Präfix, z.B. 192.168.88.0/24."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Dienst inaktiv schalten, ohne den Eintrag zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["name", "port"]
|
||||
),
|
||||
@@ -409,13 +437,14 @@ enum RouterOSSchemaCatalog {
|
||||
explanation: "Für alles außer \"Standard-Internet über eine WAN-Schnittstelle\" (das übernimmt bereits die DHCP-Client-/PPPoE-Route automatisch).",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "dst-address", label: "Zielnetz", kind: .text,
|
||||
help: "Z.B. 10.0.0.0/24, oder 0.0.0.0/0 für eine Standardroute.", required: true),
|
||||
help: "Netz mit Präfix, z.B. 10.0.0.0/24, oder 0.0.0.0/0 für eine Standardroute.", required: true),
|
||||
RouterOSFieldSchema(key: "gateway", label: "Gateway", kind: .text,
|
||||
help: "Nächster Hop — IP-Adresse oder Name eines Interfaces.", required: true),
|
||||
help: "Nächster Hop — IP-Adresse ohne Präfix (z.B. 192.168.88.254) oder Name eines Interfaces (z.B. ether1).", required: true),
|
||||
RouterOSFieldSchema(key: "distance", label: "Distanz", kind: .int,
|
||||
help: "Priorität bei mehreren passenden Routen zum selben Ziel — kleinere Zahl wird bevorzugt."),
|
||||
RouterOSFieldSchema(key: "comment", label: "Kommentar", kind: .text, help: ""),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
help: "Priorität bei mehreren passenden Routen zum selben Ziel — kleinere Zahl wird bevorzugt, z.B. 1."),
|
||||
RouterOSFieldSchema(key: "comment", label: "Kommentar", kind: .text, help: "Nur zur eigenen Wiedererkennung."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Route inaktiv schalten, ohne sie zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["dst-address", "gateway"]
|
||||
)
|
||||
@@ -442,8 +471,8 @@ enum RouterOSSchemaCatalog {
|
||||
summary: "Zugangsdaten für PPPoE-/L2TP-/PPTP-/OpenVPN-Einwahl in den Router.",
|
||||
explanation: "Jeder Benutzer kann optional einem Profil zugeordnet werden, das IP-Pool/DNS/Verschlüsselung vorgibt.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Benutzername", kind: .text, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "password", label: "Passwort", kind: .text, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "name", label: "Benutzername", kind: .text, help: "Frei wählbar, z.B. gast1.", required: true),
|
||||
RouterOSFieldSchema(key: "password", label: "Passwort", kind: .text, help: "Ausreichend lang und zufällig wählen.", required: true),
|
||||
RouterOSFieldSchema(key: "service", label: "Dienst", kind: .enumPick(options: [
|
||||
"any", "pppoe", "l2tp", "pptp", "ovpn", "sstp"
|
||||
]), help: "Für welche Einwahl-Art dieser Benutzer gilt.", defaultValue: "any"),
|
||||
@@ -451,10 +480,11 @@ enum RouterOSSchemaCatalog {
|
||||
kind: .menuItemPick(menuPath: "/ppp profile", restPath: "ppp/profile", valueField: "name"),
|
||||
help: "Name eines zuvor angelegten PPP-Profils."),
|
||||
RouterOSFieldSchema(key: "local-address", label: "Lokale Adresse", kind: .text,
|
||||
help: "IP-Adresse des Routers innerhalb dieser Verbindung."),
|
||||
help: "IP-Adresse des Routers innerhalb dieser Verbindung, ohne Präfix, z.B. 10.10.10.1."),
|
||||
RouterOSFieldSchema(key: "remote-address", label: "Adresse für den Client", kind: .text,
|
||||
help: "Feste IP für diesen Benutzer, oder Name eines Adress-Pools."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
help: "Feste IP für diesen Benutzer (z.B. 10.10.10.2), oder Name eines Adress-Pools."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Benutzer inaktiv schalten, ohne ihn zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["name", "service"]
|
||||
),
|
||||
@@ -464,11 +494,13 @@ enum RouterOSSchemaCatalog {
|
||||
summary: "Vorlagen (IP-Pool, DNS, Verschlüsselung) für PPP-Benutzer.",
|
||||
explanation: "",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "local-address", label: "Lokale Adresse", kind: .text, help: "IP-Adresse des Routers."),
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar, z.B. vpn-clients.", required: true),
|
||||
RouterOSFieldSchema(key: "local-address", label: "Lokale Adresse", kind: .text,
|
||||
help: "IP-Adresse des Routers, ohne Präfix, z.B. 10.10.10.1."),
|
||||
RouterOSFieldSchema(key: "remote-address", label: "Adress-Pool für Clients", kind: .text,
|
||||
help: "Name eines zuvor angelegten Adress-Pools."),
|
||||
RouterOSFieldSchema(key: "dns-server", label: "DNS-Server für Clients", kind: .text, help: "")
|
||||
RouterOSFieldSchema(key: "dns-server", label: "DNS-Server für Clients", kind: .text,
|
||||
help: "Ein oder mehrere Server, kommagetrennt, z.B. 1.1.1.1,8.8.8.8.")
|
||||
],
|
||||
listColumns: ["name"]
|
||||
),
|
||||
@@ -489,12 +521,14 @@ enum RouterOSSchemaCatalog {
|
||||
summary: "WLAN-Interfaces auf älteren/Standard-Wireless-Chips.",
|
||||
explanation: "Diese Interfaces existieren bereits ab Werk (ein WLAN-Chip = ein Interface) — hier werden sie nur konfiguriert, nicht neu angelegt. Ein Sicherheitsprofil (siehe \"WLAN-Sicherheitsprofile\") muss vorher angelegt sein.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "ssid", label: "Netzwerkname (SSID)", kind: .text, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "ssid", label: "Netzwerkname (SSID)", kind: .text,
|
||||
help: "Der Name, den WLAN-Geräte in der Netzwerkliste sehen, z.B. MeinWLAN.", required: true),
|
||||
RouterOSFieldSchema(key: "security-profile", label: "Sicherheitsprofil", kind: .text,
|
||||
help: "Name eines zuvor unter \"WLAN-Sicherheitsprofile\" angelegten Profils."),
|
||||
RouterOSFieldSchema(key: "mode", label: "Modus", kind: .enumPick(options: ["ap-bridge", "station", "bridge"]),
|
||||
help: "ap-bridge = Access Point (Normalfall), station = als Client mit einem anderen AP verbinden.", defaultValue: "ap-bridge"),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "WLAN-Interface inaktiv schalten, ohne es zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["ssid", "mode"]
|
||||
),
|
||||
@@ -504,7 +538,7 @@ enum RouterOSSchemaCatalog {
|
||||
summary: "Verschlüsselung/Passwort-Vorlagen für WLAN-Interfaces (Legacy-Treiber).",
|
||||
explanation: "Ein Profil wird angelegt und dann bei einem WLAN-Interface als \"security-profile\" eingetragen.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar, z.B. heimnetz-wpa2.", required: true),
|
||||
RouterOSFieldSchema(key: "mode", label: "Modus", kind: .enumPick(options: ["none", "static-keys-required", "dynamic-keys"]),
|
||||
help: "dynamic-keys ist der übliche WPA/WPA2-Modus.", defaultValue: "dynamic-keys"),
|
||||
RouterOSFieldSchema(key: "authentication-types", label: "Authentifizierung", kind: .enumPick(options: [
|
||||
@@ -521,14 +555,16 @@ enum RouterOSSchemaCatalog {
|
||||
explanation: "Anderes, verschachteltes Konfigurationsschema als der Legacy-Treiber (Punkt-Notation wie \"security.passphrase\") — nicht mit \"/interface wireless\" mischen. Nur auf Geräten mit entsprechend neuem WLAN-Chip vorhanden.",
|
||||
warning: "Diese App hat den .set-Pfad für den neuen Treiber noch nie gegen echte Hardware getestet (siehe HANDOFF.md) — nach dem Anwenden unbedingt prüfen.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "ssid", label: "Netzwerkname (SSID)", kind: .text, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "ssid", label: "Netzwerkname (SSID)", kind: .text,
|
||||
help: "Der Name, den WLAN-Geräte in der Netzwerkliste sehen, z.B. MeinWLAN.", required: true),
|
||||
RouterOSFieldSchema(key: "security.authentication-types", label: "Authentifizierung", kind: .enumPick(options: [
|
||||
"wpa2-psk", "wpa3-psk", "wpa2-psk,wpa3-psk"
|
||||
]), help: "wpa2-psk,wpa3-psk deckt sowohl ältere als auch neuere Geräte ab."),
|
||||
RouterOSFieldSchema(key: "security.passphrase", label: "Passwort", kind: .text, help: "Mindestens 8 Zeichen."),
|
||||
RouterOSFieldSchema(key: "datapath.bridge", label: "Ziel-Bridge", kind: .text,
|
||||
help: "Name der Bridge, der dieses WLAN-Netz zugeordnet wird (üblicherweise dieselbe wie das kabelgebundene LAN)."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
help: "Name der Bridge, der dieses WLAN-Netz zugeordnet wird (üblicherweise dieselbe wie das kabelgebundene LAN), z.B. bridge."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "WLAN-Interface inaktiv schalten, ohne es zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["ssid"]
|
||||
),
|
||||
@@ -546,14 +582,15 @@ enum RouterOSSchemaCatalog {
|
||||
summary: "Begrenzt Up-/Download einer IP-Adresse oder eines Netzes.",
|
||||
explanation: "Reicht für die meisten Heim-/Kleinnetz-Fälle ohne Mangle-Markierungen aus.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar.", required: true),
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar, z.B. limit-gast.", required: true),
|
||||
RouterOSFieldSchema(key: "target", label: "Ziel", kind: .text,
|
||||
help: "IP-Adresse oder Netz, das begrenzt wird, z.B. 192.168.88.50/32.", required: true),
|
||||
help: "IP-Adresse oder Netz, das begrenzt wird, mit Präfix, z.B. 192.168.88.50/32.", required: true),
|
||||
RouterOSFieldSchema(key: "max-limit", label: "Max. Bandbreite (Upload/Download)", kind: .text,
|
||||
help: "Zwei Werte getrennt durch \"/\", z.B. 10M/50M (Upload/Download).", required: true),
|
||||
RouterOSFieldSchema(key: "burst-limit", label: "Burst-Bandbreite", kind: .text,
|
||||
help: "Optional: kurzzeitig erlaubte höhere Bandbreite, z.B. 15M/60M."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Begrenzung inaktiv schalten, ohne sie zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["name", "target", "max-limit"]
|
||||
),
|
||||
@@ -564,13 +601,14 @@ enum RouterOSSchemaCatalog {
|
||||
explanation: "Statt einer festen Adresse wirkt ein Queue-Baum-Eintrag auf Verkehr mit einer bestimmten Mangle-Markierung.",
|
||||
warning: "Setzt eine passende Mangle-Regel voraus, die genau diese Markierung setzt (siehe Firewall: Mangle) — ohne die greift ein Queue-Baum-Eintrag ins Leere.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar.", required: true),
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar, z.B. queue-gast.", required: true),
|
||||
RouterOSFieldSchema(key: "parent", label: "Übergeordnet", kind: .text,
|
||||
help: "Ein Interface (z.B. der WAN-Port) oder der Name eines anderen Queue-Baum-Eintrags.", required: true),
|
||||
help: "Ein Interface (z.B. der WAN-Port, etwa ether1) oder der Name eines anderen Queue-Baum-Eintrags.", required: true),
|
||||
RouterOSFieldSchema(key: "packet-mark", label: "Paket-/Verbindungsmarkierung", kind: .text,
|
||||
help: "Name der Mangle-Markierung, auf die dieser Eintrag wirkt."),
|
||||
RouterOSFieldSchema(key: "max-limit", label: "Max. Bandbreite", kind: .text, help: "Einzelwert, z.B. 20M."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Begrenzung inaktiv schalten, ohne sie zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["name", "parent", "max-limit"]
|
||||
)
|
||||
@@ -584,7 +622,9 @@ enum RouterOSSchemaCatalog {
|
||||
displayName: "Router-Name",
|
||||
summary: "Der Name, unter dem sich der Router meldet (z.B. in Winbox/Terminal-Prompt).",
|
||||
explanation: "",
|
||||
fields: [RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "", required: true)],
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar, z.B. MeinRouter.", required: true)
|
||||
],
|
||||
listColumns: ["name"],
|
||||
isSingleton: true
|
||||
),
|
||||
@@ -605,7 +645,8 @@ enum RouterOSSchemaCatalog {
|
||||
explanation: "",
|
||||
warning: "Falsche Systemzeit kann Zertifikatsprüfungen (HTTPS/REST) und Log-Zeitstempel durcheinanderbringen.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "enabled", label: "Aktiviert", kind: .bool, help: "", defaultValue: "yes"),
|
||||
RouterOSFieldSchema(key: "enabled", label: "Aktiviert", kind: .bool,
|
||||
help: "Zeitsynchronisation ein-/ausschalten.", defaultValue: "yes"),
|
||||
RouterOSFieldSchema(key: "servers", label: "Zeitserver", kind: .text,
|
||||
help: "Ein oder mehrere Server, kommagetrennt, z.B. pool.ntp.org.")
|
||||
],
|
||||
@@ -622,14 +663,15 @@ enum RouterOSSchemaCatalog {
|
||||
explanation: "",
|
||||
warning: "Ein fehlerhaftes geplantes Skript kann unbeaufsichtigt wiederholt Änderungen vornehmen — vor dem Einplanen einmal manuell testen.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar, z.B. taeglicher-neustart.", required: true),
|
||||
RouterOSFieldSchema(key: "start-time", label: "Startzeit", kind: .text, help: "Z.B. 00:00:00 oder \"startup\"."),
|
||||
RouterOSFieldSchema(key: "interval", label: "Intervall", kind: .text,
|
||||
help: "Wie oft wiederholt wird, z.B. 1d oder 01:00:00. Leer = nur einmal zur Startzeit."),
|
||||
RouterOSFieldSchema(key: "on-event", label: "Auszuführendes Skript",
|
||||
kind: .menuItemPick(menuPath: "/system script", restPath: "system/script", valueField: "name"),
|
||||
help: "Name eines zuvor unter \"Skripte\" angelegten Skripts."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Zeitplan inaktiv schalten, ohne ihn zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["name", "interval"]
|
||||
),
|
||||
@@ -640,7 +682,7 @@ enum RouterOSSchemaCatalog {
|
||||
explanation: "",
|
||||
warning: "Skripte laufen mit den Rechten des Routers selbst — kein Unterschied zu manuell eingegebenen Befehlen.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "name", label: "Name", kind: .text, help: "Frei wählbar, z.B. backup-taeglich.", required: true),
|
||||
RouterOSFieldSchema(key: "source", label: "Skript-Inhalt", kind: .text,
|
||||
help: "RouterOS-Befehle, z.B. \":log info \\\"Test\\\"\".")
|
||||
],
|
||||
@@ -653,11 +695,12 @@ enum RouterOSSchemaCatalog {
|
||||
explanation: "",
|
||||
warning: "Das zum Verbinden genutzte eigene Konto hier nicht versehentlich löschen oder herabstufen.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "name", label: "Benutzername", kind: .text, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "password", label: "Passwort", kind: .text, help: ""),
|
||||
RouterOSFieldSchema(key: "name", label: "Benutzername", kind: .text, help: "Frei wählbar, z.B. admin2.", required: true),
|
||||
RouterOSFieldSchema(key: "password", label: "Passwort", kind: .text, help: "Ausreichend lang und zufällig wählen."),
|
||||
RouterOSFieldSchema(key: "group", label: "Rechte-Gruppe", kind: .enumPick(options: ["full", "write", "read"]),
|
||||
help: "full = Vollzugriff, write = ohne Benutzerverwaltung, read = nur lesen.", defaultValue: "full"),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Konto inaktiv schalten, ohne es zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["name", "group"]
|
||||
)
|
||||
@@ -672,12 +715,15 @@ enum RouterOSSchemaCatalog {
|
||||
summary: "Überwacht laufend, ob eine Adresse erreichbar ist, und kann bei Statuswechsel ein Skript auslösen.",
|
||||
explanation: "",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "host", label: "Zu überwachende Adresse", kind: .text, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "host", label: "Zu überwachende Adresse", kind: .text,
|
||||
help: "IP-Adresse oder Hostname, ohne Präfix, z.B. 192.168.88.1 oder 8.8.8.8.", required: true),
|
||||
RouterOSFieldSchema(key: "interval", label: "Prüf-Intervall", kind: .text, help: "Z.B. 00:00:10.", defaultValue: "00:00:10"),
|
||||
RouterOSFieldSchema(key: "up-script", label: "Skript bei Erreichbarkeit", kind: .text,
|
||||
help: "Name eines Skripts unter \"Skripte\"."),
|
||||
RouterOSFieldSchema(key: "down-script", label: "Skript bei Nichterreichbarkeit", kind: .text, help: ""),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool, help: "", defaultValue: "no")
|
||||
RouterOSFieldSchema(key: "down-script", label: "Skript bei Nichterreichbarkeit", kind: .text,
|
||||
help: "Name eines Skripts unter \"Skripte\"."),
|
||||
RouterOSFieldSchema(key: "disabled", label: "Deaktiviert", kind: .bool,
|
||||
help: "Überwachung inaktiv schalten, ohne sie zu löschen.", defaultValue: "no")
|
||||
],
|
||||
listColumns: ["host"]
|
||||
),
|
||||
@@ -687,11 +733,12 @@ enum RouterOSSchemaCatalog {
|
||||
summary: "Postausgangs-Server, den Scheduler/Netwatch/Skripte für Benachrichtigungen nutzen.",
|
||||
explanation: "Ein einzelner, geräteweiter Satz Einstellungen — kein Menü mit mehreren Einträgen.",
|
||||
fields: [
|
||||
RouterOSFieldSchema(key: "address", label: "Mailserver-Adresse", kind: .text, help: "", required: true),
|
||||
RouterOSFieldSchema(key: "address", label: "Mailserver-Adresse", kind: .text,
|
||||
help: "Hostname oder IP-Adresse des Mailservers, z.B. smtp.gmail.com.", required: true),
|
||||
RouterOSFieldSchema(key: "port", label: "Port", kind: .int, help: "Meist 587 (STARTTLS) oder 465 (SSL)."),
|
||||
RouterOSFieldSchema(key: "from", label: "Absenderadresse", kind: .text, help: ""),
|
||||
RouterOSFieldSchema(key: "user", label: "Benutzername", kind: .text, help: ""),
|
||||
RouterOSFieldSchema(key: "password", label: "Passwort", kind: .text, help: "")
|
||||
RouterOSFieldSchema(key: "from", label: "Absenderadresse", kind: .text, help: "Z.B. router@example.com."),
|
||||
RouterOSFieldSchema(key: "user", label: "Benutzername", kind: .text, help: "Zugangsdaten des Mailservers."),
|
||||
RouterOSFieldSchema(key: "password", label: "Passwort", kind: .text, help: "Zugangsdaten des Mailservers.")
|
||||
],
|
||||
listColumns: ["address"],
|
||||
isSingleton: true
|
||||
|
||||
@@ -7,6 +7,12 @@ struct ExpertMenuDetailView: View {
|
||||
var body: some View {
|
||||
Form {
|
||||
Section {
|
||||
Text(schema.displayName)
|
||||
.font(.title2)
|
||||
.bold()
|
||||
Text(schema.category.rawValue)
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
Text(schema.explanation)
|
||||
if let warning = schema.warning {
|
||||
Label(warning, systemImage: "exclamationmark.triangle")
|
||||
|
||||
@@ -25,8 +25,19 @@ struct ExpertView: View {
|
||||
if !schemas.isEmpty {
|
||||
Section(category.rawValue) {
|
||||
ForEach(schemas) { schema in
|
||||
Button(schema.displayName) {
|
||||
let isSelected = viewModel.selectedSchema?.menuPath == schema.menuPath
|
||||
Button {
|
||||
viewModel.open(schema)
|
||||
} label: {
|
||||
Text(schema.displayName)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(.vertical, 4)
|
||||
.padding(.horizontal, 6)
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 6)
|
||||
.fill(isSelected ? Color.blue.opacity(0.25) : Color.clear)
|
||||
)
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user