network/nix/pkgs/switches/junos.nix

139 lines
3.7 KiB
Nix

{ pkgs, hostName, config, hostConfig
, sortBy, sortNetsByVlan
, ... }:
with pkgs;
with lib;
let
configFile = builtins.toFile "junos.config" ''
system {
host-name ${hostName};
time-zone Europe/Berlin;
root-authentication {
encrypted-password "$5$EBmFELmv$kQxtWwS0SBS.TqVPRvs8sKpH./l9DTtTxX/I2FJB2n2"; ## SECRET-DATA
ssh-ed25519 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHGgoLzQMeyX1wjsX/hgVkN//zyfOQPiBRYgO2ajEGH6 root@server2";
}
services {
ssh {
root-login allow;
}
netconf {
ssh;
}
web-management {
http {
interface [ vme.0 vlan.1 ];
}
}
}
}
protocols {
lldp {
interface all;
}
}
virtual-chassis {
no-split-detection;
member 0 {
mastership-priority 255;
}
member 1 {
mastership-priority 255;
}
}
chassis { aggregated-devices { ethernet { device-count 32; } } }
vlans {
${concatMapStrings (net:
let
netName = if net == "mgmt"
then "mgmt-vlan"
else net;
netConfig = config.site.net.${net};
vlan = toString netConfig.vlan;
in
lib.optionalString (netConfig.vlan != null) ''
${netName} {
vlan-id ${vlan};
${lib.optionalString (net == "mgmt") ''
l3-interface vlan.${vlan};
''}
}
''
) (sortNetsByVlan (builtins.attrNames config.site.net))}
}
interfaces {
vlan {
unit ${toString config.site.net.mgmt.vlan} {
family inet {
address ${mgmtAddress}/${toString config.site.net.mgmt.subnet4Len};
}
}
}
${concatMapStrings (name:
let
linkConfig = hostConfig.links.${name};
group = linkConfig.group;
isBond = linkConfig.group != null &&
builtins.length linkConfig.ports > 1;
nets = map (net:
if net == "mgmt"
then "mgmt-vlan"
else net
) linkConfig.nets;
vlanConfig = ''
unit 0 {
family ethernet-switching {
port-mode ${if linkConfig.trunk then "trunk" else "access"};
vlan { members [ ${concatStringsSep " " nets} ]; }
}
}
'';
in
if isBond
then concatMapStrings (port: ''
${port} {
ether-options { 802.3ad ae${group}; }
}
'') (linkConfig.ports) + ''
ae${group} {
aggregated-ether-options { lacp { active; } }
${vlanConfig}
}
''
else concatMapStrings (port: ''
${port} {
${vlanConfig}
}
'') (linkConfig.ports)
) (sortBy (link: hostConfig.links.${link}.ports)
(builtins.attrNames hostConfig.links)
)}
}
'';
configFileWithHash = runCommand "junos.config" {
nativeBuildInputs = [ python3 ];
} ''
cat >gen.py<<EOF
import crypt
print(crypt.crypt('${hostConfig.password}', crypt.mksalt(crypt.METHOD_SHA256)))
EOF
HASH=$(python gen.py)
substitute ${configFile} $out \
--replace "%%HASH%%" "$HASH"
'';
mgmtAddress = config.site.net.mgmt.hosts4.${hostName};
in ''
#! ${runtimeShell} -e
scp ${configFileWithHash} root@${mgmtAddress}:/tmp/junos.config
ssh root@${mgmtAddress} cli <<EOF
configure
load override /tmp/junos.config
commit
EOF
''