Merge pull request 'refactor' (#1) from refactor into master
Reviewed-on: lbailly/Netconf-Module#1
This commit is contained in:
commit
841ff3a69e
8 changed files with 522 additions and 351 deletions
114
default.nix
114
default.nix
|
@ -2,82 +2,66 @@
|
||||||
pkgs ? (import <nixpkgs> { }),
|
pkgs ? (import <nixpkgs> { }),
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
moduleEX2300 = import ./moduleMaker.nix [
|
lib = pkgs.lib;
|
||||||
"ge-0/0/0"
|
hive_mod =
|
||||||
"ge-0/0/1"
|
{
|
||||||
"ge-0/0/2"
|
lib,
|
||||||
"ge-0/0/3"
|
config,
|
||||||
"ge-0/0/4"
|
name,
|
||||||
"ge-0/0/5"
|
...
|
||||||
"ge-0/0/6"
|
}:
|
||||||
"ge-0/0/7"
|
with lib;
|
||||||
"ge-0/0/8"
|
{
|
||||||
"ge-0/0/9"
|
options.deployment = {
|
||||||
"ge-0/0/10"
|
targetHost = mkOption { type = types.str; };
|
||||||
"ge-0/0/11"
|
rpc = mkOption {
|
||||||
"ge-0/0/12"
|
type = types.package;
|
||||||
"ge-0/0/13"
|
readOnly = true;
|
||||||
"ge-0/0/14"
|
};
|
||||||
"ge-0/0/15"
|
cmd = mkOption {
|
||||||
"ge-0/0/16"
|
type = types.package;
|
||||||
"ge-0/0/17"
|
readOnly = true;
|
||||||
"ge-0/0/18"
|
};
|
||||||
"ge-0/0/19"
|
};
|
||||||
"ge-0/0/20"
|
config.deployment = rec {
|
||||||
"ge-0/0/21"
|
rpc = pkgs.writeText "config-${name}_rpc.xml" ''
|
||||||
"ge-0/0/22"
|
<rpc>
|
||||||
"ge-0/0/23"
|
<edit-config>
|
||||||
"ge-0/0/24"
|
<config>
|
||||||
"ge-0/0/25"
|
${config.netconf.xmls.configuration}
|
||||||
"ge-0/0/26"
|
</config>
|
||||||
"ge-0/0/27"
|
<target>
|
||||||
"ge-0/0/28"
|
<candidate/>
|
||||||
"ge-0/0/29"
|
</target>
|
||||||
"ge-0/0/30"
|
</edit-config>
|
||||||
"ge-0/0/31"
|
</rpc>
|
||||||
"ge-0/0/32"
|
<rpc>
|
||||||
"ge-0/0/33"
|
<commit/>
|
||||||
"ge-0/0/34"
|
</rpc>
|
||||||
"ge-0/0/35"
|
'';
|
||||||
"ge-0/0/36"
|
cmd = pkgs.writeShellApplication {
|
||||||
"ge-0/0/37"
|
name = "deploy-${name}.sh";
|
||||||
"ge-0/0/38"
|
runtimeInputs = with pkgs; [ openssh ];
|
||||||
"ge-0/0/39"
|
text = ''ssh "${config.deployment.targetHost}" -p 830 -s netconf < ${rpc}'';
|
||||||
"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"
|
|
||||||
];
|
|
||||||
evaluator =
|
evaluator =
|
||||||
name: module_inst:
|
name: module_inst:
|
||||||
let
|
let
|
||||||
cfg = pkgs.lib.evalModules {
|
cfg = pkgs.lib.evalModules {
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit pkgs name;
|
inherit name;
|
||||||
};
|
};
|
||||||
modules = [
|
modules = [
|
||||||
moduleEX2300
|
./junos
|
||||||
|
./ex2300.nix
|
||||||
|
hive_mod
|
||||||
module_inst
|
module_inst
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
"ln -s ${cfg.config.deployement.cmd} $out/${name}";
|
"ln -s ${lib.getExe cfg.config.deployment.cmd} $out/${name}";
|
||||||
hive = import ./netconf-hive.nix;
|
hive = import ./netconf-hive.nix;
|
||||||
cmds = builtins.attrValues (builtins.mapAttrs evaluator hive);
|
cmds = builtins.attrValues (builtins.mapAttrs evaluator hive);
|
||||||
in
|
in
|
||||||
|
|
62
ex2300.nix
Normal file
62
ex2300.nix
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
{
|
||||||
|
netconf.mandatoryInterfaces = [
|
||||||
|
"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"
|
||||||
|
];
|
||||||
|
}
|
36
junos/default.nix
Normal file
36
junos/default.nix
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
name,
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./protocols.nix
|
||||||
|
./interfaces.nix
|
||||||
|
./vlans.nix
|
||||||
|
];
|
||||||
|
options = {
|
||||||
|
netconf.xmls.configuration = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
|
netconf.mandatoryInterfaces = mkOption { type = types.listOf types.str; };
|
||||||
|
};
|
||||||
|
config.interfaces =
|
||||||
|
let
|
||||||
|
mkIntf = name: {
|
||||||
|
inherit name;
|
||||||
|
value.enable = mkDefault false;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
listToAttrs (map mkIntf config.netconf.mandatoryInterfaces);
|
||||||
|
config.netconf.xmls.configuration = ''
|
||||||
|
<configuration>
|
||||||
|
${config.netconf.xmls.interfaces}
|
||||||
|
${config.netconf.xmls.protocols}
|
||||||
|
${config.netconf.xmls.vlans}
|
||||||
|
</configuration>
|
||||||
|
'';
|
||||||
|
}
|
131
junos/interfaces.nix
Normal file
131
junos/interfaces.nix
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
interface =
|
||||||
|
{ name, config, ... }:
|
||||||
|
let
|
||||||
|
intf-name = name;
|
||||||
|
unit =
|
||||||
|
{ name, config, ... }:
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
enable = mkEnableOption "the logical interface ${intf-name}.${name}" // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
family = {
|
||||||
|
ethernet-switching = {
|
||||||
|
enable = mkEnableOption "the ethernet on the logical interface ${intf-name}.${name}";
|
||||||
|
interface-mode = mkOption {
|
||||||
|
type = types.nullOr (
|
||||||
|
types.enum [
|
||||||
|
"trunk"
|
||||||
|
"access"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
vlans = mkOption {
|
||||||
|
type = types.listOf (types.either types.str types.ints.unsigned);
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
#TODO : DHCP
|
||||||
|
inet = {
|
||||||
|
enable = mkEnableOption "the IPv4 configuration of the logical interface ${intf-name}.${name}";
|
||||||
|
address = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
inet6 = {
|
||||||
|
enable = mkEnableOption "the IPv6 configuration of the logical interface ${intf-name}.${name}";
|
||||||
|
address = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
xml = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
visible = false;
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config.xml =
|
||||||
|
let
|
||||||
|
members = map (
|
||||||
|
vlan: "<members>${builtins.toString vlan}</members>"
|
||||||
|
) config.family.ethernet-switching.vlans;
|
||||||
|
eth = optionalString config.family.ethernet-switching.enable ''
|
||||||
|
<ethernet-switching>
|
||||||
|
<interface-mode>${config.family.ethernet-switching.interface-mode}</interface-mode>
|
||||||
|
<vlan>${builtins.concatStringsSep "" members}</vlan>
|
||||||
|
<storm-control><profile-name>default</profile-name></storm-control>
|
||||||
|
</ethernet-switching>
|
||||||
|
'';
|
||||||
|
|
||||||
|
addr4 = map (addr: "<name>${addr}</name>") config.family.inet.address;
|
||||||
|
inet = optionalString config.family.inet.enable ''
|
||||||
|
<inet>
|
||||||
|
<address>${builtins.concatStringsSep "" addr4}</address>
|
||||||
|
</inet>
|
||||||
|
'';
|
||||||
|
|
||||||
|
addr6 = map (addr: "<name>${addr}</name>") config.family.inet6.address;
|
||||||
|
inet6 = optionalString config.family.inet6.enable ''
|
||||||
|
<inet6>
|
||||||
|
<address>${builtins.concatStringsSep "" addr6}</address>
|
||||||
|
</inet6>
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
''
|
||||||
|
<unit>
|
||||||
|
<name>${name}</name>
|
||||||
|
${optionalString (!config.enable) "<disable/>"}
|
||||||
|
<family>
|
||||||
|
${eth}${inet}${inet6}
|
||||||
|
</family>
|
||||||
|
</unit>'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
enable = mkEnableOption "the physical interface ${intf-name}";
|
||||||
|
unit = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule unit);
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
xml = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
visible = false;
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config.xml =
|
||||||
|
let
|
||||||
|
units = attrsets.mapAttrsToList (_: unit: unit.xml) config.unit;
|
||||||
|
in
|
||||||
|
''
|
||||||
|
<interface>
|
||||||
|
<name>${name}</name>
|
||||||
|
${optionalString (!config.enable) "<disable/>"}
|
||||||
|
${builtins.concatStringsSep "" units}
|
||||||
|
</interface>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
interfaces = mkOption { type = types.attrsOf (types.submodule interface); };
|
||||||
|
netconf.xmls.interfaces = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
visible = false;
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config.netconf.xmls.interfaces = ''
|
||||||
|
<interfaces operation="replace">
|
||||||
|
${builtins.concatStringsSep "" (attrsets.mapAttrsToList (_: intf: intf.xml) config.interfaces)}
|
||||||
|
</interfaces>
|
||||||
|
'';
|
||||||
|
}
|
23
junos/protocols.nix
Normal file
23
junos/protocols.nix
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
protocols.rstp = mkOption { type = types.listOf types.str; };
|
||||||
|
netconf.xmls.protocols = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
visible = false;
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config.netconf.xmls.protocols =
|
||||||
|
let
|
||||||
|
rstps = map (intf: "<interface><name>${intf}</name></interface>") config.protocols.rstp;
|
||||||
|
in
|
||||||
|
''
|
||||||
|
<protocols>
|
||||||
|
<rstp operation="replace">
|
||||||
|
${concatStringsSep "" rstps}
|
||||||
|
</rstp>
|
||||||
|
</protocols>
|
||||||
|
'';
|
||||||
|
}
|
76
junos/vlans.nix
Normal file
76
junos/vlans.nix
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
vlan =
|
||||||
|
{ name, config, ... }:
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
id = mkOption {
|
||||||
|
type = types.nullOr types.ints.unsigned;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
id-list = mkOption {
|
||||||
|
type =
|
||||||
|
let
|
||||||
|
range_type =
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
config.__toString = _: "${toString config.begin}-${toString config.end}";
|
||||||
|
options = {
|
||||||
|
begin = mkOption { type = types.ints.unsigned; };
|
||||||
|
end = mkOption { type = types.ints.unsigned; };
|
||||||
|
__toString = mkOption {
|
||||||
|
visible = false;
|
||||||
|
internal = true;
|
||||||
|
readOnly = true;
|
||||||
|
type = types.unspecified;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
types.listOf (types.either types.ints.unsigned (types.submodule range_type));
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
l3-interface = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
xml = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
readOnly = true;
|
||||||
|
visible = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config.xml =
|
||||||
|
let
|
||||||
|
id = optionalString (!isNull config.id) "<vlan-id>${toString config.id}</vlan-id>";
|
||||||
|
id-list = concatStringsSep "" (
|
||||||
|
map (vlan: "<vlan-id-list>${toString vlan}</vlan-id-list>") config.id-list
|
||||||
|
);
|
||||||
|
l3-intf = optionalString (
|
||||||
|
!isNull config.l3-interface
|
||||||
|
) "<l3-interface>${config.l3-interface}</l3-interface>";
|
||||||
|
in
|
||||||
|
''
|
||||||
|
<vlan>
|
||||||
|
<name>${name}</name>
|
||||||
|
${id}${id-list}${l3-intf}
|
||||||
|
</vlan>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
vlans = mkOption { type = types.attrsOf (types.submodule vlan); };
|
||||||
|
netconf.xmls.vlans = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
visible = false;
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config.netconf.xmls.vlans = ''
|
||||||
|
<vlans operation="replace">
|
||||||
|
${builtins.concatStringsSep "" (attrsets.mapAttrsToList (_: vlan: vlan.xml) config.vlans)}
|
||||||
|
</vlans>
|
||||||
|
'';
|
||||||
|
}
|
241
moduleMaker.nix
241
moduleMaker.nix
|
@ -1,241 +0,0 @@
|
||||||
interfaces:
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config;
|
|
||||||
in
|
|
||||||
with lib;
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
deployement = {
|
|
||||||
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 = [ ];
|
|
||||||
};
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
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
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
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; }
|
|
||||||
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}
|
|
||||||
'';
|
|
||||||
}
|
|
190
netconf-hive.nix
190
netconf-hive.nix
|
@ -1,103 +1,203 @@
|
||||||
let
|
let
|
||||||
vlansPlan = mgmt: {
|
vlansPlan = {
|
||||||
"uplink-cri".ids = 223;
|
"uplink-cri".id = 223;
|
||||||
|
|
||||||
"admin-core" = {
|
"admin-core" = {
|
||||||
ids = 3000;
|
id = 3000;
|
||||||
management = mgmt;
|
l3-interface = "irb.0";
|
||||||
};
|
};
|
||||||
"admin-ap".ids = 3001;
|
"admin-ap".id = 3001;
|
||||||
"users".ids = [
|
"users".id-list = [
|
||||||
{
|
{
|
||||||
begin = 3045;
|
begin = 3045;
|
||||||
end = 4094;
|
end = 4094;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
"ap-staging".ids = 2000;
|
"ap-staging".id = 2000;
|
||||||
};
|
};
|
||||||
AP = {
|
AP = {
|
||||||
enable = true;
|
enable = true;
|
||||||
interface-mode = "trunk";
|
unit."0".family.ethernet-switching = {
|
||||||
vlans = [
|
enable = true;
|
||||||
"users"
|
interface-mode = "trunk";
|
||||||
"admin-ap"
|
vlans = [
|
||||||
];
|
"users"
|
||||||
|
"admin-ap"
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
AP-staging = {
|
AP-staging = {
|
||||||
enable = true;
|
enable = true;
|
||||||
interface-mode = "access";
|
unit."0".family.ethernet-switching = {
|
||||||
vlans = [ "ap-staging" ];
|
enable = true;
|
||||||
|
interface-mode = "access";
|
||||||
|
vlans = [ "ap-staging" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
netcore01 = {
|
netcore02 = {
|
||||||
deployement.targetHost = "jourdan01.dgn";
|
deployment.targetHost = "netcore02.dgn";
|
||||||
|
vlans = vlansPlan;
|
||||||
|
protocols.rstp = [
|
||||||
|
"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/42"
|
||||||
|
"ge-0/0/43"
|
||||||
|
"ge-0/0/47"
|
||||||
|
|
||||||
vlans = vlansPlan "fd26:baf9:d250:8000::1001/64";
|
"xe-0/1/0"
|
||||||
|
"xe-0/1/1"
|
||||||
|
"ge-0/1/3"
|
||||||
|
];
|
||||||
interfaces = {
|
interfaces = {
|
||||||
"ge-0/0/12" = AP;
|
"ge-0/0/0" = AP-staging;
|
||||||
"ge-0/0/13" = AP;
|
"ge-0/0/1" = AP-staging;
|
||||||
"ge-0/0/14" = AP;
|
"ge-0/0/2" = AP-staging;
|
||||||
"ge-0/0/15" = AP;
|
"ge-0/0/3" = AP-staging;
|
||||||
"ge-0/0/16" = AP;
|
"ge-0/0/4" = AP-staging;
|
||||||
"ge-0/0/17" = AP;
|
"ge-0/0/5" = AP-staging;
|
||||||
|
"ge-0/0/6" = AP-staging;
|
||||||
|
"ge-0/0/7" = AP-staging;
|
||||||
|
"ge-0/0/8" = AP-staging;
|
||||||
|
"ge-0/0/9" = AP-staging;
|
||||||
|
"ge-0/0/10" = AP-staging;
|
||||||
|
"ge-0/0/11" = AP-staging;
|
||||||
|
"ge-0/0/12" = AP-staging;
|
||||||
|
"ge-0/0/13" = AP-staging;
|
||||||
|
"ge-0/0/14" = AP-staging;
|
||||||
|
"ge-0/0/15" = AP-staging;
|
||||||
|
"ge-0/0/16" = AP-staging;
|
||||||
|
"ge-0/0/17" = AP-staging;
|
||||||
|
|
||||||
"ge-0/0/42" = {
|
"ge-0/0/42" = {
|
||||||
enable = true;
|
enable = true;
|
||||||
interface-mode = "access";
|
unit."0".family.ethernet-switching = {
|
||||||
vlans = [ "admin-core" ];
|
enable = true;
|
||||||
|
interface-mode = "trunk";
|
||||||
|
vlans = [ "all" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
"ge-0/0/43" = AP-staging;
|
"ge-0/0/43" = AP-staging;
|
||||||
"ge-0/0/47" = {
|
"ge-0/0/47" = {
|
||||||
# ilo
|
# ilo
|
||||||
enable = true;
|
enable = true;
|
||||||
interface-mode = "access";
|
unit."0".family.ethernet-switching = {
|
||||||
vlans = [ "admin-core" ];
|
enable = true;
|
||||||
|
interface-mode = "access";
|
||||||
|
vlans = [ "admin-core" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
"xe-0/1/0" = {
|
"xe-0/1/0" = {
|
||||||
enable = true;
|
enable = true;
|
||||||
interface-mode = "trunk";
|
unit."0".family.ethernet-switching = {
|
||||||
vlans = [ "all" ];
|
enable = true;
|
||||||
dhcp_trusted = true;
|
interface-mode = "trunk";
|
||||||
|
vlans = [ "all" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
"xe-0/1/1" = {
|
"xe-0/1/1" = {
|
||||||
enable = true;
|
enable = true;
|
||||||
interface-mode = "trunk";
|
unit."0".family.ethernet-switching = {
|
||||||
vlans = [
|
enable = true;
|
||||||
"users"
|
interface-mode = "trunk";
|
||||||
"admin-ap"
|
vlans = [
|
||||||
"admin-core"
|
"users"
|
||||||
];
|
"admin-ap"
|
||||||
|
"admin-core"
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
"ge-0/1/3" = {
|
"ge-0/1/3" = {
|
||||||
enable = true;
|
enable = true;
|
||||||
interface-mode = "trunk";
|
unit."0".family.ethernet-switching = {
|
||||||
vlans = [ "uplink-cri" ];
|
enable = true;
|
||||||
|
interface-mode = "trunk";
|
||||||
|
vlans = [ "uplink-cri" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
"me0" = {
|
"me0" = {
|
||||||
enable = true;
|
enable = true;
|
||||||
management = "192.168.42.6/24";
|
unit."0".family.inet = {
|
||||||
|
enable = true;
|
||||||
|
address = [ "192.168.42.6/24" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
"irb" = {
|
||||||
|
enable = true;
|
||||||
|
unit."0".family.inet6 = {
|
||||||
|
enable = true;
|
||||||
|
address = [ "fd26:baf9:d250:8000::1001/64" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
netaccess01 = {
|
netaccess01 = {
|
||||||
deployement.targetHost = "root@192.168.42.6";
|
deployment.targetHost = "netaccess01.dgn";
|
||||||
|
|
||||||
vlans = vlansPlan "fd26:baf9:d250:8000::2001/64";
|
vlans = vlansPlan;
|
||||||
|
|
||||||
|
protocols.rstp = [
|
||||||
|
"ge-0/0/0"
|
||||||
|
"ge-0/0/1"
|
||||||
|
"ge-0/0/2"
|
||||||
|
"ge-0/0/3"
|
||||||
|
"ge-0/0/4"
|
||||||
|
"ge-0/0/5"
|
||||||
|
|
||||||
|
"xe-0/1/0"
|
||||||
|
];
|
||||||
interfaces = {
|
interfaces = {
|
||||||
|
"ge-0/0/0" = AP-staging;
|
||||||
|
"ge-0/0/1" = AP-staging;
|
||||||
|
"ge-0/0/2" = AP-staging;
|
||||||
|
"ge-0/0/3" = AP-staging;
|
||||||
|
"ge-0/0/4" = AP-staging;
|
||||||
|
"ge-0/0/5" = AP-staging;
|
||||||
|
|
||||||
"xe-0/1/0" = {
|
"xe-0/1/0" = {
|
||||||
enable = true;
|
enable = true;
|
||||||
interface-mode = "trunk";
|
unit."0".family.ethernet-switching = {
|
||||||
vlans = [ "all" ];
|
enable = true;
|
||||||
dhcp_trusted = true;
|
interface-mode = "trunk";
|
||||||
|
vlans = [ "all" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
"me0" = {
|
"me0" = {
|
||||||
enable = true;
|
enable = true;
|
||||||
management = "192.168.42.6/24";
|
unit."0".family.inet = {
|
||||||
|
enable = true;
|
||||||
|
address = [ "192.168.42.6/24" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
"irb" = {
|
||||||
|
enable = true;
|
||||||
|
unit."0".family.inet6 = {
|
||||||
|
enable = true;
|
||||||
|
address = [ "fd26:baf9:d250:8000::2001/64" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue