diff --git a/configMaker.nix b/configMaker.nix index 27bcd56..4ab6644 100644 --- a/configMaker.nix +++ b/configMaker.nix @@ -1,182 +1,105 @@ let module_inst = { - interfaces = - let AP = { # AP - interface-mode = "trunk"; - vlans = [ "users" "admin" ]; - }; - off.interface-mode = "none"; - in { - "ge-0/0/0" = off; - "ge-0/0/1" = off; - "ge-0/0/2" = off; - "ge-0/0/3" = off; - "ge-0/0/4" = off; - "ge-0/0/5" = off; - "ge-0/0/6" = off; - "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; + interfaces = let + AP = { # AP + enable = true; + interface-mode = "trunk"; + vlans = [ "users" "admin" ]; + }; + off.enable = false; + in { + "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/1/0" = { # upstream - interface-mode = "trunk"; - vlans = [ "all" ]; - dhcp_trusted = true; - 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; - }; + "ge-0/1/1" = { + enable = true; + interface-mode = "trunk"; + vlans = [ "uplink-cri" ]; }; - vlans = { - "users" = [ { begin = 3045; end = 4094; } ]; - "admin" = [ 3000 ]; + + "xe-0/1/0" = { # upstream + enable = true; + interface-mode = "trunk"; + vlans = [ "all" ]; + dhcp_trusted = true; + }; + + "me0" = { # mgmt + enable = true; + management = true; }; }; - module = { lib, config, ... }: with lib; { - # NOTE: dhcp should be configured at vlan level, but this is not very satisfying, - # so this module tries to configured dhcp-trust on interfaces - # -> this implies that interfaces change the config of their vlans - 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 "" else ""; - eth_switch = if config.interface-mode == "none" then "" else '' - - ${config.interface-mode} - ${builtins.concatStringsSep "" (map (vlan: "${builtins.toString vlan}") config.vlans)} - ''; - in '' - - ${name} - - 0 - - ${mgmt_fam} - ${eth_switch} - - - ''; - }; - 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; - }; + vlans = { + "users" = [ { begin = 3045; end = 4094; } ]; + "admin" = [ 3000 ]; + "uplink-cri" = [ 223 ]; }; - 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 ''${list}'') - config.vlans.${vlan}; - in '' - - ${vlan} - ${builtins.concatStringsSep "\n" ids} - '') (builtins.attrNames config.vlans); - in [ '' - - ${builtins.concatStringsSep "\n" interfaces} - - - ${builtins.concatStringsSep "\n" 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 ).evalModules { modules = [ module module_inst ]; } diff --git a/moduleMaker.nix b/moduleMaker.nix new file mode 100644 index 0000000..538a311 --- /dev/null +++ b/moduleMaker.nix @@ -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 "" else ""; + # FIXME : need to enforce address in reality + mgmt_fam = if cfg.interfaces.${name}.management then "" else ""; + members = map (vlan: "${builtins.toString vlan}") cfg.interfaces.${name}.vlans; + eth_switch = if builtins.isNull cfg.interfaces.${name}.interface-mode then "" else '' + + ${cfg.interfaces.${name}.interface-mode} + ${builtins.concatStringsSep "" members} + ''; + in '' + + ${name} + ${disable_flag} + + 0 + + ${mgmt_fam} + ${eth_switch} + + + ''; + 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 ''${list}''; + vlan_map = vlan: let + ids = map id_map cfg.vlans.${vlan}; + in '' + + ${vlan} + ${builtins.concatStringsSep "\n" ids} + ''; + in map vlan_map (builtins.attrNames cfg.vlans); + in [ '' + + ${builtins.concatStringsSep "\n" interface_xmls} + + + ${builtins.concatStringsSep "\n" vlans} + '' vlan_trust_table + ]; +}