Netconf-Module/moduleMaker.nix

106 lines
3.4 KiB
Nix

interfaces:
{ lib, config, ... }:
let cfg = config;
in with lib; {
options = {
vlans = let
range_type.options = {
begin = mkOption { type = types.ints.unsigned; };
end = mkOption { type = types.ints.unsigned; };
};
in mkOption {
type = types.attrsOf (types.listOf (types.either types.ints.unsigned (types.submodule range_type)));
};
interfaces = let
template = name: {
enable = mkEnableOption "the interface ${name}";
interface-mode = mkOption {
type = types.nullOr (types.enum [ "trunk" "access" ]);
default = null;
};
vlans = mkOption {
type = let
vlan_type = types.either (types.strMatching "[^\n\r]+") (types.ints.unsigned);
in types.listOf vlan_type;
default = [ ];
};
dhcp_trusted = mkOption {
type = types.bool;
default = false;
};
management = mkOption {
type = types.bool;
default = false;
};
};
in builtins.listToAttrs (map (name: { inherit name; value = template name; }) interfaces);
toplevel = mkOption {
type = types.unspecified;
visible = false;
readOnly = true;
};
};
config.toplevel = let
intf_xmlGen = name: let
disable_flag = if !cfg.interfaces.${name}.enable then "<disable/>" else "";
# FIXME : need to enforce address in reality
mgmt_fam = if cfg.interfaces.${name}.management then "<inet><dhcp/></inet>" else "";
members = map (vlan: "<members>${builtins.toString vlan}</members>") cfg.interfaces.${name}.vlans;
eth_switch = if builtins.isNull cfg.interfaces.${name}.interface-mode then "" else ''
<ethernet-switching>
<interface-mode>${cfg.interfaces.${name}.interface-mode}</interface-mode>
<vlan>${builtins.concatStringsSep "" members}</vlan>
</ethernet-switching>'';
in ''
<interface>
<name>${name}</name>
${disable_flag}
<unit>
<name>0</name>
<family>
${mgmt_fam}
${eth_switch}
</family>
</unit>
</interface>'';
interface_xmls = map intf_xmlGen interfaces;
vlan_trust_table = let
vlan_map = inter: vlan:
if builtins.isString vlan then
if cfg.interfaces.${inter}.dhcp_trusted then
{ ${vlan}.trust = inter; }
else
{ ${vlan}.notrust = inter; }
else
{};
int_map = inter: map (vlan_map inter) cfg.interfaces.${inter}.vlans;
in builtins.zipAttrsWith
(vlan: values: builtins.zipAttrsWith (_: ints: ints ) values)
(builtins.concatMap int_map interfaces);
vlans = let
id_map = id: let
list =
if builtins.isInt id then
builtins.toString id
else
"${builtins.toString id.begin}-${builtins.toString id.end}";
in ''<vlan-id-list>${list}</vlan-id-list>'';
vlan_map = vlan: let
ids = map id_map cfg.vlans.${vlan};
in ''
<vlan>
<name>${vlan}</name>
${builtins.concatStringsSep "\n" ids}
</vlan>'';
in map vlan_map (builtins.attrNames cfg.vlans);
in [ ''
<interfaces>
${builtins.concatStringsSep "\n" interface_xmls}
</interfaces>
<vlans>
${builtins.concatStringsSep "\n" vlans}
</vlans>'' vlan_trust_table
];
}