module refactor to control the ports
This commit is contained in:
parent
942db1bc92
commit
c8fd1d84e7
2 changed files with 201 additions and 172 deletions
267
configMaker.nix
267
configMaker.nix
|
@ -1,182 +1,105 @@
|
||||||
let module_inst = {
|
let module_inst = {
|
||||||
interfaces =
|
interfaces = let
|
||||||
let AP = { # AP
|
AP = { # AP
|
||||||
interface-mode = "trunk";
|
enable = true;
|
||||||
vlans = [ "users" "admin" ];
|
interface-mode = "trunk";
|
||||||
};
|
vlans = [ "users" "admin" ];
|
||||||
off.interface-mode = "none";
|
};
|
||||||
in {
|
off.enable = false;
|
||||||
"ge-0/0/0" = off;
|
in {
|
||||||
"ge-0/0/1" = off;
|
"ge-0/0/12" = AP;
|
||||||
"ge-0/0/2" = off;
|
"ge-0/0/13" = AP;
|
||||||
"ge-0/0/3" = off;
|
"ge-0/0/14" = AP;
|
||||||
"ge-0/0/4" = off;
|
"ge-0/0/15" = AP;
|
||||||
"ge-0/0/5" = off;
|
"ge-0/0/16" = AP;
|
||||||
"ge-0/0/6" = off;
|
"ge-0/0/17" = AP;
|
||||||
"ge-0/0/7" = off;
|
|
||||||
"ge-0/0/8" = off;
|
|
||||||
"ge-0/0/9" = off;
|
|
||||||
"ge-0/0/10" = off;
|
|
||||||
"ge-0/0/11" = off;
|
|
||||||
"ge-0/0/12" = AP;
|
|
||||||
"ge-0/0/13" = AP;
|
|
||||||
"ge-0/0/14" = AP;
|
|
||||||
"ge-0/0/15" = AP;
|
|
||||||
"ge-0/0/16" = AP;
|
|
||||||
"ge-0/0/17" = AP;
|
|
||||||
"ge-0/0/18" = off;
|
|
||||||
"ge-0/0/19" = off;
|
|
||||||
"ge-0/0/20" = off;
|
|
||||||
"ge-0/0/21" = off;
|
|
||||||
"ge-0/0/22" = off;
|
|
||||||
"ge-0/0/23" = off;
|
|
||||||
"ge-0/0/24" = off;
|
|
||||||
"ge-0/0/25" = off;
|
|
||||||
"ge-0/0/26" = off;
|
|
||||||
"ge-0/0/27" = off;
|
|
||||||
"ge-0/0/28" = off;
|
|
||||||
"ge-0/0/29" = off;
|
|
||||||
"ge-0/0/30" = off;
|
|
||||||
"ge-0/0/31" = off;
|
|
||||||
"ge-0/0/32" = off;
|
|
||||||
"ge-0/0/33" = off;
|
|
||||||
"ge-0/0/34" = off;
|
|
||||||
"ge-0/0/35" = off;
|
|
||||||
"ge-0/0/36" = off;
|
|
||||||
"ge-0/0/37" = off;
|
|
||||||
"ge-0/0/38" = off;
|
|
||||||
"ge-0/0/39" = off;
|
|
||||||
"ge-0/0/40" = off;
|
|
||||||
"ge-0/0/41" = off;
|
|
||||||
"ge-0/0/42" = off;
|
|
||||||
"ge-0/0/43" = off;
|
|
||||||
"ge-0/0/44" = off;
|
|
||||||
"ge-0/0/45" = off;
|
|
||||||
"ge-0/0/46" = off;
|
|
||||||
"ge-0/0/47" = off;
|
|
||||||
|
|
||||||
"ge-0/1/0" = { # upstream
|
"ge-0/1/1" = {
|
||||||
interface-mode = "trunk";
|
enable = true;
|
||||||
vlans = [ "all" ];
|
interface-mode = "trunk";
|
||||||
dhcp_trusted = true;
|
vlans = [ "uplink-cri" ];
|
||||||
management = true;
|
|
||||||
};
|
|
||||||
"ge-0/1/1" = off;
|
|
||||||
"ge-0/1/2" = off;
|
|
||||||
"ge-0/1/3" = off;
|
|
||||||
|
|
||||||
"xe-0/1/0" = off;
|
|
||||||
"xe-0/1/1" = off;
|
|
||||||
"xe-0/1/2" = off;
|
|
||||||
"xe-0/1/3" = off;
|
|
||||||
|
|
||||||
"me0" = { # mgmt
|
|
||||||
interface-mode = "none";
|
|
||||||
management = true;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
vlans = {
|
|
||||||
"users" = [ { begin = 3045; end = 4094; } ];
|
"xe-0/1/0" = { # upstream
|
||||||
"admin" = [ 3000 ];
|
enable = true;
|
||||||
|
interface-mode = "trunk";
|
||||||
|
vlans = [ "all" ];
|
||||||
|
dhcp_trusted = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
"me0" = { # mgmt
|
||||||
|
enable = true;
|
||||||
|
management = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
module = { lib, config, ... }: with lib; {
|
vlans = {
|
||||||
# NOTE: dhcp should be configured at vlan level, but this is not very satisfying,
|
"users" = [ { begin = 3045; end = 4094; } ];
|
||||||
# so this module tries to configured dhcp-trust on interfaces
|
"admin" = [ 3000 ];
|
||||||
# -> this implies that interfaces change the config of their vlans
|
"uplink-cri" = [ 223 ];
|
||||||
options = {
|
|
||||||
interfaces =
|
|
||||||
let vlan_type = types.either (types.strMatching "[^\n\r]+") (types.ints.unsigned);
|
|
||||||
interface = {config, ...}: {
|
|
||||||
options = {
|
|
||||||
interface-mode = mkOption {
|
|
||||||
type = types.enum [ "trunk" "access" "none" ];
|
|
||||||
#TODO: default = if ;
|
|
||||||
};
|
|
||||||
vlans = mkOption {
|
|
||||||
type = types.listOf vlan_type;
|
|
||||||
};
|
|
||||||
dhcp_trusted = mkOption { type = types.bool; default = false; };
|
|
||||||
management = mkOption { type = types.bool; default = false; };
|
|
||||||
|
|
||||||
xmlGen = mkOption { type = types.uniq types.unspecified; };
|
|
||||||
};
|
|
||||||
config.vlans = lib.mkIf (config.interface-mode == "none") (lib.mkForce [ ]);
|
|
||||||
config.xmlGen = name:
|
|
||||||
let
|
|
||||||
mgmt_fam = if config.management then "<inet><dhcp/></inet>" else "";
|
|
||||||
eth_switch = if config.interface-mode == "none" then "" else ''
|
|
||||||
<ethernet-switching>
|
|
||||||
<interface-mode>${config.interface-mode}</interface-mode>
|
|
||||||
<vlan>${builtins.concatStringsSep "" (map (vlan: "<members>${builtins.toString vlan}</members>") config.vlans)}</vlan>
|
|
||||||
</ethernet-switching>'';
|
|
||||||
in ''
|
|
||||||
<interface>
|
|
||||||
<name>${name}</name>
|
|
||||||
<unit>
|
|
||||||
<name>0</name>
|
|
||||||
<family>
|
|
||||||
${mgmt_fam}
|
|
||||||
${eth_switch}
|
|
||||||
</family>
|
|
||||||
</unit>
|
|
||||||
</interface>'';
|
|
||||||
};
|
|
||||||
in mkOption {
|
|
||||||
type = types.attrsOf (types.submodule interface);
|
|
||||||
};
|
|
||||||
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)));
|
|
||||||
};
|
|
||||||
|
|
||||||
# NOTE, HACK: placeholder for now
|
|
||||||
toplevel = mkOption {
|
|
||||||
type = types.uniq types.anything;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
config.toplevel =
|
|
||||||
let
|
|
||||||
interfaces = builtins.attrValues (builtins.mapAttrs (name: mod: mod.xmlGen name) config.interfaces);
|
|
||||||
# { vlan = { trust = [String]; notrust = [String]; } }
|
|
||||||
interface_names = builtins.attrNames config.interfaces;
|
|
||||||
vlan_map = inter: vlan:
|
|
||||||
if builtins.isString vlan then
|
|
||||||
if config.interfaces.${inter}.dhcp_trusted then
|
|
||||||
{ ${vlan}.trust = inter; }
|
|
||||||
else
|
|
||||||
{ ${vlan}.notrust = inter; }
|
|
||||||
else
|
|
||||||
{};
|
|
||||||
int_map = inter: map (vlan_map inter) config.interfaces.${inter}.vlans;
|
|
||||||
vlan_trust_table =
|
|
||||||
builtins.zipAttrsWith (vlan: values: builtins.zipAttrsWith (_: ints: ints ) values)
|
|
||||||
(builtins.concatMap int_map interface_names);
|
|
||||||
vlans = map (vlan:
|
|
||||||
let ids = 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>'')
|
|
||||||
config.vlans.${vlan};
|
|
||||||
in ''
|
|
||||||
<vlan>
|
|
||||||
<name>${vlan}</name>
|
|
||||||
${builtins.concatStringsSep "\n" ids}
|
|
||||||
</vlan>'') (builtins.attrNames config.vlans);
|
|
||||||
in [ ''
|
|
||||||
<interfaces>
|
|
||||||
${builtins.concatStringsSep "\n" interfaces}
|
|
||||||
</interfaces>
|
|
||||||
<vlans>
|
|
||||||
${builtins.concatStringsSep "\n" vlans}
|
|
||||||
</vlans>'' vlan_trust_table];
|
|
||||||
};
|
};
|
||||||
|
module = import ./moduleMaker.nix [
|
||||||
|
"ge-0/0/0"
|
||||||
|
"ge-0/0/1"
|
||||||
|
"ge-0/0/2"
|
||||||
|
"ge-0/0/3"
|
||||||
|
"ge-0/0/4"
|
||||||
|
"ge-0/0/5"
|
||||||
|
"ge-0/0/6"
|
||||||
|
"ge-0/0/7"
|
||||||
|
"ge-0/0/8"
|
||||||
|
"ge-0/0/9"
|
||||||
|
"ge-0/0/10"
|
||||||
|
"ge-0/0/11"
|
||||||
|
"ge-0/0/12"
|
||||||
|
"ge-0/0/13"
|
||||||
|
"ge-0/0/14"
|
||||||
|
"ge-0/0/15"
|
||||||
|
"ge-0/0/16"
|
||||||
|
"ge-0/0/17"
|
||||||
|
"ge-0/0/18"
|
||||||
|
"ge-0/0/19"
|
||||||
|
"ge-0/0/20"
|
||||||
|
"ge-0/0/21"
|
||||||
|
"ge-0/0/22"
|
||||||
|
"ge-0/0/23"
|
||||||
|
"ge-0/0/24"
|
||||||
|
"ge-0/0/25"
|
||||||
|
"ge-0/0/26"
|
||||||
|
"ge-0/0/27"
|
||||||
|
"ge-0/0/28"
|
||||||
|
"ge-0/0/29"
|
||||||
|
"ge-0/0/30"
|
||||||
|
"ge-0/0/31"
|
||||||
|
"ge-0/0/32"
|
||||||
|
"ge-0/0/33"
|
||||||
|
"ge-0/0/34"
|
||||||
|
"ge-0/0/35"
|
||||||
|
"ge-0/0/36"
|
||||||
|
"ge-0/0/37"
|
||||||
|
"ge-0/0/38"
|
||||||
|
"ge-0/0/39"
|
||||||
|
"ge-0/0/40"
|
||||||
|
"ge-0/0/41"
|
||||||
|
"ge-0/0/42"
|
||||||
|
"ge-0/0/43"
|
||||||
|
"ge-0/0/44"
|
||||||
|
"ge-0/0/45"
|
||||||
|
"ge-0/0/46"
|
||||||
|
"ge-0/0/47"
|
||||||
|
|
||||||
|
"ge-0/1/0"
|
||||||
|
"ge-0/1/1"
|
||||||
|
"ge-0/1/2"
|
||||||
|
"ge-0/1/3"
|
||||||
|
|
||||||
|
"xe-0/1/0"
|
||||||
|
"xe-0/1/1"
|
||||||
|
"xe-0/1/2"
|
||||||
|
"xe-0/1/3"
|
||||||
|
|
||||||
|
"me0"
|
||||||
|
];
|
||||||
in (import <nixpkgs/lib>).evalModules {
|
in (import <nixpkgs/lib>).evalModules {
|
||||||
modules = [ module module_inst ];
|
modules = [ module module_inst ];
|
||||||
}
|
}
|
||||||
|
|
106
moduleMaker.nix
Normal file
106
moduleMaker.nix
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
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
|
||||||
|
];
|
||||||
|
}
|
Loading…
Reference in a new issue