{ lib, config, xml, ... }: let inherit (lib) mkOption assertMsg mapAttrsToList mkMerge mkIf ; inherit (lib.types) nullOr ints unspecified listOf either submodule str attrsOf ; vlan = { name, config, ... }: { options = { id = mkOption { type = nullOr ints.unsigned; default = null; description = '' The ID of this vlan, `null` means no ID. Incompatible with vlans.${name}.id-list. ''; }; id-list = mkOption { type = let range_type = { config, ... }: { config.__toString = _: "${toString config.begin}-${toString config.end}"; options = { begin = mkOption { type = ints.unsigned; visible = false; }; end = mkOption { type = ints.unsigned; visible = false; }; __toString = mkOption { visible = false; internal = true; readOnly = true; type = unspecified; }; }; }; in listOf (either ints.unsigned (submodule range_type)); default = [ ]; example = [ 42 { begin = 100; end = 200; } ]; description = '' List of IDs or IDs range to classify as this vlan. Incompatible with vlans.${name}.id. ''; }; l3-interface = mkOption { type = nullOr str; default = null; example = "irb.0"; description = '' Switch's logical interface to connect directly to this vlan. This allows to communicate with the switch from a vlan without having a cable looping back on it's management interface. ''; }; xml = mkOption { type = xml.type; readOnly = true; visible = false; }; }; config.xml = let id = mkIf (!isNull config.id) { vlan-id = toString config.id; }; id-list = mkIf (config.id-list != [ ]) { vlan-id-list = map toString config.id-list; }; l3-intf = mkIf (!isNull config.l3-interface) { inherit (config) l3-interface; }; in assert assertMsg ( config.id == null || config.id-list == [ ] ) "vlans.${name}.id and vlans.${name}.id-list are incompatible."; mkMerge [ { inherit name; } id id-list l3-intf ]; }; in { options = { vlans = mkOption { type = attrsOf (submodule vlan); description = '' Named vlans configuration. Allows to name vlans inside interface configuration, instead of just using their IDs. ''; }; }; config.netconf.xml.vlans = { "@operation" = "replace"; vlan = mapAttrsToList (_: vlan: vlan.xml) config.vlans; }; }