Files
Mikrotik-Installer/src/MikrotikInstaller.Core/Configuration/VlanConfigurator.cs
T
adminandClaude Sonnet 5 e58480d2ae
Build / build (push) Canceled after 0s
Experten-Modus hinzufügen: erweiterte RouterOS-Optionen in WAN/LAN/VLAN/WLAN/Firewall
Neuer Wizard-Schritt "Modus wählen" nach der Geräte-Erkennung, mit dem
zwischen dem geführten Assistenten und einem Experten-Modus gewählt werden
kann. Im Experten-Modus zeigen die bestehenden Schritte zusätzliche,
technischere Felder (DHCP-Feinsteuerung, MTU, WPA3, Portbereiche,
IP-Sperrlisten, VLAN-Isolation u.a.), die im Laien-Modus verborgen bleiben.
Alle neuen Settings-Felder sind optional mit Defaults, die das bisherige
Verhalten unverändert lassen (45 Tests grün, 7 davon neu für die
Experten-Felder).

Zusätzlich zwei beim Live-Testen gefundene Bugs behoben: der letzte Schritt
zeigte einen dauerhaft ausgegrauten "Weiter"-Button statt eines
"Beenden"-Buttons, und die Texte im neuen Moduswahl-Schritt wurden
abgeschnitten (horizontales StackPanel gab TextBlocks unbegrenzte Breite
zum Messen, dadurch griff TextWrapping nicht — behoben durch Grid mit
fester Spaltenbreite).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 18:14:04 +02:00

104 lines
4.8 KiB
C#

namespace MikrotikInstaller.Core.Configuration;
/// <summary>
/// Erzeugt aus den Wizard-Eingaben zusätzliche, logisch getrennte Netzwerke: je VLAN eine eigene
/// VLAN-Schnittstelle auf der Heimnetz-Bridge mit eigenem Adressbereich und eigenem DHCP-Server.
/// </summary>
public static class VlanConfigurator
{
public static IReadOnlyList<ConfigurationAction> BuildActions(string parentBridgeName, IReadOnlyList<VlanDefinition> vlans)
{
var actions = new List<ConfigurationAction>();
foreach (var vlan in vlans)
{
var interfaceName = $"vlan{vlan.VlanId}";
var routerAddress = vlan.RouterAddressCidr.Split('/')[0];
var networkCidr = IpNetworkHelper.GetNetworkCidr(vlan.RouterAddressCidr);
var poolName = $"pool-{interfaceName}";
var dhcpServerName = $"dhcp-{interfaceName}";
actions.Add(new ConfigurationAction(
$"VLAN „{vlan.Name}\" (ID {vlan.VlanId}) auf „{parentBridgeName}\" anlegen",
(client, ct) => client.AddAsync("/interface/vlan", new Dictionary<string, string>
{
["name"] = interfaceName,
["interface"] = parentBridgeName,
["vlan-id"] = vlan.VlanId.ToString(),
}, ct)));
actions.Add(new ConfigurationAction(
$"IP-Adresse {vlan.RouterAddressCidr} für VLAN „{vlan.Name}\" einrichten",
(client, ct) => client.AddAsync("/ip/address", new Dictionary<string, string>
{
["address"] = vlan.RouterAddressCidr,
["interface"] = interfaceName,
}, ct)));
actions.Add(new ConfigurationAction(
$"IP-Adressbereich {vlan.DhcpPoolStart}-{vlan.DhcpPoolEnd} für VLAN „{vlan.Name}\" reservieren",
(client, ct) => client.AddAsync("/ip/pool", new Dictionary<string, string>
{
["name"] = poolName,
["ranges"] = $"{vlan.DhcpPoolStart}-{vlan.DhcpPoolEnd}",
}, ct)));
var dhcpServerParameters = new Dictionary<string, string>
{
["name"] = dhcpServerName,
["interface"] = interfaceName,
["address-pool"] = poolName,
["disabled"] = "no",
};
if (!string.IsNullOrWhiteSpace(vlan.DhcpLeaseTime))
{
dhcpServerParameters["lease-time"] = vlan.DhcpLeaseTime;
}
actions.Add(new ConfigurationAction(
$"DHCP-Server für VLAN „{vlan.Name}\" aktivieren",
(client, ct) => client.AddAsync("/ip/dhcp-server", dhcpServerParameters, ct)));
actions.Add(new ConfigurationAction(
$"Netzwerk-Einstellungen (Gateway {routerAddress}) für VLAN „{vlan.Name}\" hinterlegen",
(client, ct) => client.AddAsync("/ip/dhcp-server/network", new Dictionary<string, string>
{
["address"] = networkCidr,
["gateway"] = routerAddress,
["dns-server"] = string.IsNullOrWhiteSpace(vlan.DnsServerOverride) ? routerAddress : vlan.DnsServerOverride,
}, ct)));
if (vlan.IsolateFromLan)
{
actions.Add(new ConfigurationAction(
$"VLAN „{vlan.Name}\" vom Heimnetz „{parentBridgeName}\" isolieren",
(client, ct) => client.AddAsync("/ip/firewall/filter", new Dictionary<string, string>
{
["chain"] = "forward",
["in-interface"] = interfaceName,
["out-interface"] = parentBridgeName,
["action"] = "drop",
}, ct)));
actions.Add(new ConfigurationAction(
$"Heimnetz „{parentBridgeName}\" vor Zugriff aus VLAN „{vlan.Name}\" schützen",
(client, ct) => client.AddAsync("/ip/firewall/filter", new Dictionary<string, string>
{
["chain"] = "forward",
["in-interface"] = parentBridgeName,
["out-interface"] = interfaceName,
["action"] = "drop",
}, ct)));
}
}
return actions;
}
/// <summary>Kurze, laientaugliche Zusammenfassung für den Zusammenfassungs-Schritt (keine RouterOS-Fachbegriffe).</summary>
public static IReadOnlyList<string> BuildFriendlySummary(IReadOnlyList<VlanDefinition> vlans) =>
vlans
.Select(vlan => $"„{vlan.Name}\" — ein eigenes, getrenntes Netzwerk ({IpNetworkHelper.GetNetworkCidr(vlan.RouterAddressCidr)}).")
.ToList();
}