chore(fmt): applied nixfmt
This commit is contained in:
parent
f084f0e1ad
commit
813e4d24a5
3 changed files with 262 additions and 190 deletions
30
default.nix
30
default.nix
|
@ -1,4 +1,6 @@
|
|||
{ pkgs ? (import <nixpkgs> {}) }:
|
||||
{
|
||||
pkgs ? (import <nixpkgs> { }),
|
||||
}:
|
||||
let
|
||||
moduleEX2300 = import ./moduleMaker.nix [
|
||||
"ge-0/0/0"
|
||||
|
@ -62,17 +64,21 @@ let
|
|||
|
||||
"me0"
|
||||
];
|
||||
evaluator = name: module_inst:
|
||||
let cfg = pkgs.lib.evalModules {
|
||||
specialArgs = { inherit pkgs name; };
|
||||
modules = [
|
||||
moduleEX2300
|
||||
module_inst
|
||||
];
|
||||
};
|
||||
in "ln -s ${cfg.config.deployement.cmd} $out/${name}";
|
||||
evaluator =
|
||||
name: module_inst:
|
||||
let
|
||||
cfg = pkgs.lib.evalModules {
|
||||
specialArgs = {
|
||||
inherit pkgs name;
|
||||
};
|
||||
modules = [
|
||||
moduleEX2300
|
||||
module_inst
|
||||
];
|
||||
};
|
||||
in
|
||||
"ln -s ${cfg.config.deployement.cmd} $out/${name}";
|
||||
hive = import ./netconf-hive.nix;
|
||||
cmds = builtins.attrValues (builtins.mapAttrs evaluator hive);
|
||||
in
|
||||
pkgs.runCommand "netconf-deploy" {}
|
||||
(builtins.concatStringsSep "\n" ([ "mkdir $out" ] ++ cmds))
|
||||
pkgs.runCommand "netconf-deploy" { } (builtins.concatStringsSep "\n" ([ "mkdir $out" ] ++ cmds))
|
||||
|
|
398
moduleMaker.nix
398
moduleMaker.nix
|
@ -1,189 +1,241 @@
|
|||
interfaces:
|
||||
{ name, lib, pkgs, config, ... }:
|
||||
let cfg = config;
|
||||
in with lib; {
|
||||
{
|
||||
name,
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config;
|
||||
in
|
||||
with lib;
|
||||
{
|
||||
options = {
|
||||
deployement = {
|
||||
targetHost = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
targetHost = mkOption { type = types.str; };
|
||||
cmd = mkOption {
|
||||
type = types.package;
|
||||
readOnly = true;
|
||||
};
|
||||
};
|
||||
vlans = let
|
||||
range_type.options = {
|
||||
begin = mkOption { type = types.ints.unsigned; };
|
||||
end = mkOption { type = types.ints.unsigned; };
|
||||
};
|
||||
vlan_type.options = {
|
||||
ids = mkOption {
|
||||
type = types.either
|
||||
types.ints.unsigned
|
||||
(types.listOf (types.either types.ints.unsigned (types.submodule range_type)));
|
||||
default = [ ];
|
||||
vlans =
|
||||
let
|
||||
range_type.options = {
|
||||
begin = mkOption { type = types.ints.unsigned; };
|
||||
end = mkOption { type = types.ints.unsigned; };
|
||||
};
|
||||
management = mkOption {
|
||||
# FIXME : support ipv4, either static or dhcp (with the coffee)
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
IP address with wich to permit management on this vlan.
|
||||
Only one vlan can set an IP (this module limitation, not switch).
|
||||
'';
|
||||
vlan_type.options = {
|
||||
ids = mkOption {
|
||||
type = types.either types.ints.unsigned (
|
||||
types.listOf (types.either types.ints.unsigned (types.submodule range_type))
|
||||
);
|
||||
default = [ ];
|
||||
};
|
||||
management = mkOption {
|
||||
# FIXME : support ipv4, either static or dhcp (with the coffee)
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
IP address with wich to permit management on this vlan.
|
||||
Only one vlan can set an IP (this module limitation, not switch).
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
in mkOption {
|
||||
type = types.attrsOf (types.submodule vlan_type);
|
||||
};
|
||||
interfaces = let
|
||||
template = name: {
|
||||
enable = mkEnableOption "the interface ${name}";
|
||||
interface-mode = mkOption {
|
||||
type = types.nullOr (types.enum [ "trunk" "access" ]);
|
||||
default = null;
|
||||
in
|
||||
mkOption { type = types.attrsOf (types.submodule vlan_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 = [ ];
|
||||
};
|
||||
# TODO: use this option
|
||||
dhcp_trusted = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
management = mkOption {
|
||||
# FIXME : support ipv6, either static or dhcp (with the coffee)
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
vlans = mkOption {
|
||||
type = let
|
||||
vlan_type = types.either (types.strMatching "[^\n\r]+") (types.ints.unsigned);
|
||||
in types.listOf vlan_type;
|
||||
default = [ ];
|
||||
};
|
||||
# TODO: use this option
|
||||
dhcp_trusted = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
management = mkOption {
|
||||
# FIXME : support ipv6, either static or dhcp (with the coffee)
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
in builtins.listToAttrs (map (name: { inherit name; value = template name; }) interfaces);
|
||||
in
|
||||
builtins.listToAttrs (
|
||||
map (name: {
|
||||
inherit name;
|
||||
value = template name;
|
||||
}) interfaces
|
||||
);
|
||||
};
|
||||
|
||||
config.deployement.cmd = 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 !builtins.isNull cfg.interfaces.${name}.management then ''
|
||||
<inet>
|
||||
<address>
|
||||
<name>${cfg.interfaces.${name}.management}</name>
|
||||
</address>
|
||||
</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>
|
||||
<storm-control><profile-name>default</profile-name></storm-control>
|
||||
</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;
|
||||
rstp_gen = name:
|
||||
if cfg.interfaces.${name}.enable && !builtins.isNull cfg.interfaces.${name}.interface-mode then
|
||||
"<interface><name>${name}</name></interface>"
|
||||
else "";
|
||||
rstps = map rstp_gen interfaces;
|
||||
vlan_trust_table = let
|
||||
vlan_map = inter: vlan:
|
||||
if builtins.isString vlan && cfg.interfaces.${inter}.enable then
|
||||
if cfg.interfaces.${inter}.dhcp_trusted then
|
||||
{ ${vlan}.trust = inter; }
|
||||
else
|
||||
{ ${vlan}.notrust = inter; }
|
||||
config.deployement.cmd =
|
||||
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 !builtins.isNull cfg.interfaces.${name}.management then
|
||||
''
|
||||
<inet>
|
||||
<address>
|
||||
<name>${cfg.interfaces.${name}.management}</name>
|
||||
</address>
|
||||
</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>
|
||||
<storm-control><profile-name>default</profile-name></storm-control>
|
||||
</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;
|
||||
rstp_gen =
|
||||
name:
|
||||
if cfg.interfaces.${name}.enable && !builtins.isNull cfg.interfaces.${name}.interface-mode then
|
||||
"<interface><name>${name}</name></interface>"
|
||||
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 = if !builtins.isList cfg.vlans.${vlan}.ids then
|
||||
[ "<vlan-id>${builtins.toString cfg.vlans.${vlan}.ids}</vlan-id>" ]
|
||||
else map id_map cfg.vlans.${vlan}.ids;
|
||||
mgmt_flag = if !builtins.isNull cfg.vlans.${vlan}.management
|
||||
then "<l3-interface>irb.0</l3-interface>" else "";
|
||||
in ''
|
||||
<vlan>
|
||||
<name>${vlan}</name>
|
||||
${mgmt_flag}
|
||||
${builtins.concatStringsSep "\n" ids}
|
||||
</vlan>'';
|
||||
in map vlan_map (builtins.attrNames cfg.vlans);
|
||||
irb_intf = let
|
||||
addresses = map (vlan: vlan.management) (builtins.attrValues cfg.vlans);
|
||||
addr = builtins.foldl' (acc: addr: if !builtins.isNull addr then addr else acc) null addresses;
|
||||
in if !builtins.isNull addr then ''
|
||||
<interface>
|
||||
<name>irb</name>
|
||||
<unit>
|
||||
<name>0</name>
|
||||
<family>
|
||||
<inet6>
|
||||
<address><name>${addr}</name></address>
|
||||
</inet6>
|
||||
</family>
|
||||
</unit>
|
||||
</interface>
|
||||
''
|
||||
else "";
|
||||
config = ''
|
||||
<interfaces operation="replace">
|
||||
${builtins.concatStringsSep "\n" interface_xmls}
|
||||
${irb_intf}
|
||||
</interfaces>
|
||||
<protocols>
|
||||
<rstp operation="replace">
|
||||
${builtins.concatStringsSep "\n" rstps}
|
||||
</rstp>
|
||||
</protocols>
|
||||
<vlans operation="replace">
|
||||
${builtins.concatStringsSep "\n" vlans}
|
||||
</vlans>
|
||||
'';
|
||||
rpc_requests = pkgs.writeText "config-${name}_rpc.xml" ''
|
||||
<rpc>
|
||||
<edit-config>
|
||||
<config>
|
||||
<configuration>
|
||||
${config}
|
||||
</configuration>
|
||||
</config>
|
||||
<target>
|
||||
<candidate/>
|
||||
</target>
|
||||
</edit-config>
|
||||
</rpc>
|
||||
<rpc>
|
||||
<commit/>
|
||||
</rpc>
|
||||
'';
|
||||
in pkgs.writeShellScript "deploy-${name}.sh" ''
|
||||
"";
|
||||
rstps = map rstp_gen interfaces;
|
||||
vlan_trust_table =
|
||||
let
|
||||
vlan_map =
|
||||
inter: vlan:
|
||||
if builtins.isString vlan && cfg.interfaces.${inter}.enable 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 =
|
||||
if !builtins.isList cfg.vlans.${vlan}.ids then
|
||||
[ "<vlan-id>${builtins.toString cfg.vlans.${vlan}.ids}</vlan-id>" ]
|
||||
else
|
||||
map id_map cfg.vlans.${vlan}.ids;
|
||||
mgmt_flag =
|
||||
if !builtins.isNull cfg.vlans.${vlan}.management then "<l3-interface>irb.0</l3-interface>" else "";
|
||||
in
|
||||
''
|
||||
<vlan>
|
||||
<name>${vlan}</name>
|
||||
${mgmt_flag}
|
||||
${builtins.concatStringsSep "\n" ids}
|
||||
</vlan>'';
|
||||
in
|
||||
map vlan_map (builtins.attrNames cfg.vlans);
|
||||
irb_intf =
|
||||
let
|
||||
addresses = map (vlan: vlan.management) (builtins.attrValues cfg.vlans);
|
||||
addr = builtins.foldl' (acc: addr: if !builtins.isNull addr then addr else acc) null addresses;
|
||||
in
|
||||
if !builtins.isNull addr then
|
||||
''
|
||||
<interface>
|
||||
<name>irb</name>
|
||||
<unit>
|
||||
<name>0</name>
|
||||
<family>
|
||||
<inet6>
|
||||
<address><name>${addr}</name></address>
|
||||
</inet6>
|
||||
</family>
|
||||
</unit>
|
||||
</interface>
|
||||
''
|
||||
else
|
||||
"";
|
||||
config = ''
|
||||
<interfaces operation="replace">
|
||||
${builtins.concatStringsSep "\n" interface_xmls}
|
||||
${irb_intf}
|
||||
</interfaces>
|
||||
<protocols>
|
||||
<rstp operation="replace">
|
||||
${builtins.concatStringsSep "\n" rstps}
|
||||
</rstp>
|
||||
</protocols>
|
||||
<vlans operation="replace">
|
||||
${builtins.concatStringsSep "\n" vlans}
|
||||
</vlans>
|
||||
'';
|
||||
rpc_requests = pkgs.writeText "config-${name}_rpc.xml" ''
|
||||
<rpc>
|
||||
<edit-config>
|
||||
<config>
|
||||
<configuration>
|
||||
${config}
|
||||
</configuration>
|
||||
</config>
|
||||
<target>
|
||||
<candidate/>
|
||||
</target>
|
||||
</edit-config>
|
||||
</rpc>
|
||||
<rpc>
|
||||
<commit/>
|
||||
</rpc>
|
||||
'';
|
||||
in
|
||||
pkgs.writeShellScript "deploy-${name}.sh" ''
|
||||
${pkgs.openssh}/bin/ssh ${cfg.deployement.targetHost} -p 830 -s netconf < ${rpc_requests}
|
||||
''
|
||||
;
|
||||
'';
|
||||
}
|
||||
|
|
|
@ -7,21 +7,30 @@ let
|
|||
management = mgmt;
|
||||
};
|
||||
"admin-ap".ids = 3001;
|
||||
"users".ids = [ { begin = 3045; end = 4094; } ];
|
||||
"users".ids = [
|
||||
{
|
||||
begin = 3045;
|
||||
end = 4094;
|
||||
}
|
||||
];
|
||||
|
||||
"ap-staging".ids = 2000;
|
||||
};
|
||||
AP = {
|
||||
enable = true;
|
||||
interface-mode = "trunk";
|
||||
vlans = [ "users" "admin-ap" ];
|
||||
vlans = [
|
||||
"users"
|
||||
"admin-ap"
|
||||
];
|
||||
};
|
||||
AP-staging = {
|
||||
enable = true;
|
||||
interface-mode = "access";
|
||||
vlans = [ "ap-staging" ];
|
||||
};
|
||||
in {
|
||||
in
|
||||
{
|
||||
netcore01 = {
|
||||
deployement.targetHost = "jourdan01.dgn";
|
||||
|
||||
|
@ -40,7 +49,8 @@ in {
|
|||
vlans = [ "admin-core" ];
|
||||
};
|
||||
"ge-0/0/43" = AP-staging;
|
||||
"ge-0/0/47" = { # ilo
|
||||
"ge-0/0/47" = {
|
||||
# ilo
|
||||
enable = true;
|
||||
interface-mode = "access";
|
||||
vlans = [ "admin-core" ];
|
||||
|
@ -55,7 +65,11 @@ in {
|
|||
"xe-0/1/1" = {
|
||||
enable = true;
|
||||
interface-mode = "trunk";
|
||||
vlans = [ "users" "admin-ap" "admin-core" ];
|
||||
vlans = [
|
||||
"users"
|
||||
"admin-ap"
|
||||
"admin-core"
|
||||
];
|
||||
};
|
||||
"ge-0/1/3" = {
|
||||
enable = true;
|
||||
|
|
Loading…
Reference in a new issue