forked from zentralwerk/network
lib/config/options: rewrite getHostLinkNetworks et al
This commit is contained in:
parent
7834d64e27
commit
001aaecf3a
|
@ -2,53 +2,49 @@
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
getHostNets = link:
|
# A host needs to know a network if it
|
||||||
|
# - is a configured interface, or
|
||||||
|
# - is required behind at least two different links
|
||||||
|
getHostLinkNetworks = hostName: link:
|
||||||
let
|
let
|
||||||
hostConfig = config.site.hosts.${link};
|
hostConfig = config.site.hosts.${hostName};
|
||||||
sort = nets: lib.unique (
|
# all the host's links
|
||||||
builtins.sort (net1: net2:
|
hostLinkNetworks = builtins.mapAttrs (link: _:
|
||||||
config.site.net.${net1}.vlan < config.site.net.${net2}.vlan
|
networksBehindLink hostName link
|
||||||
) nets
|
) hostConfig.links;
|
||||||
);
|
# how many links have a net in networksBehindLink
|
||||||
|
networkLinkCount = net:
|
||||||
|
builtins.length (
|
||||||
|
builtins.filter (builtins.elem net)
|
||||||
|
(builtins.attrValues hostLinkNetworks)
|
||||||
|
);
|
||||||
in
|
in
|
||||||
if config.site.hosts ? ${link}
|
# access port
|
||||||
then
|
if config.site.net ? ${link}
|
||||||
sort (
|
|
||||||
builtins.attrNames hostConfig.interfaces ++
|
|
||||||
getLinksNets link
|
|
||||||
)
|
|
||||||
|
|
||||||
else if config.site.net ? ${link}
|
|
||||||
then [ link ]
|
then [ link ]
|
||||||
|
|
||||||
else builtins.trace "Don't know what nets to configure for link to \"${link}\"" [];
|
# multiple vlans on this link
|
||||||
|
else
|
||||||
|
builtins.filter (net:
|
||||||
|
# this port and local interface
|
||||||
|
hostConfig.interfaces ? ${net}
|
||||||
|
||
|
||||||
|
# this port and another
|
||||||
|
networkLinkCount net > 1
|
||||||
|
) hostLinkNetworks.${link};
|
||||||
|
|
||||||
# breaks the getHostNets recursion for switches,
|
networksBehindLink = hostName: name:
|
||||||
# requiring any net to be used by at >1 links
|
networksBehindLink' {
|
||||||
getLinksNets = hostName:
|
"${hostName}" = true;
|
||||||
let
|
} [ name ];
|
||||||
linksNets = builtins.mapAttrs (link: _:
|
|
||||||
unique (
|
|
||||||
getLinkNets { "${hostName}" = true; } [ link ]
|
|
||||||
)
|
|
||||||
) config.site.hosts.${hostName}.links;
|
|
||||||
allNets = unique (
|
|
||||||
builtins.concatLists (builtins.attrValues linksNets)
|
|
||||||
);
|
|
||||||
netLinkCount = net:
|
|
||||||
builtins.foldl' (netLinkCount: nets:
|
|
||||||
if builtins.elem net nets
|
|
||||||
then netLinkCount + 1
|
|
||||||
else netLinkCount
|
|
||||||
) 0 (builtins.attrValues linksNets);
|
|
||||||
nets = builtins.filter (net:
|
|
||||||
netLinkCount net > 1
|
|
||||||
) allNets;
|
|
||||||
in nets;
|
|
||||||
|
|
||||||
getLinkNets = seen: links:
|
networksBehindLink' = seen: links:
|
||||||
if links == []
|
if links == []
|
||||||
then []
|
then
|
||||||
|
# Done, result is the seen link names that are networks:
|
||||||
|
builtins.filter (name:
|
||||||
|
config.site.net ? ${name}
|
||||||
|
) (builtins.attrNames seen)
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
link = builtins.head links;
|
link = builtins.head links;
|
||||||
|
@ -59,13 +55,17 @@ let
|
||||||
links' = builtins.tail links;
|
links' = builtins.tail links;
|
||||||
in
|
in
|
||||||
if config.site.hosts ? ${link}
|
if config.site.hosts ? ${link}
|
||||||
then getLinkNets seen' (
|
then networksBehindLink' seen' (
|
||||||
links' ++ (
|
links' ++ (
|
||||||
|
builtins.attrNames config.site.hosts.${link}.interfaces
|
||||||
|
) ++ (
|
||||||
onlyUnseen (builtins.attrNames config.site.hosts.${link}.links)
|
onlyUnseen (builtins.attrNames config.site.hosts.${link}.links)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else getHostNets link ++
|
else if config.site.net ? ${link}
|
||||||
getLinkNets seen' (onlyUnseen links');
|
then networksBehindLink' seen' links'
|
||||||
|
|
||||||
|
else throw "Link to invalid target ${link}";
|
||||||
|
|
||||||
dhcpOpts = {
|
dhcpOpts = {
|
||||||
start = mkOption {
|
start = mkOption {
|
||||||
|
@ -382,7 +382,7 @@ let
|
||||||
links = mkOption {
|
links = mkOption {
|
||||||
description = "Which port is connected to what other device? Keys are either network names or known hostnames.";
|
description = "Which port is connected to what other device? Keys are either network names or known hostnames.";
|
||||||
default = {};
|
default = {};
|
||||||
type = with types; attrsOf (submodule linkOpts);
|
type = with types; attrsOf (submodule (linkOpts name));
|
||||||
};
|
};
|
||||||
wifi = mkOption {
|
wifi = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
|
@ -433,7 +433,7 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
linkOpts = { name, ... }: {
|
linkOpts = hostName: { name, ... }: {
|
||||||
options = {
|
options = {
|
||||||
ports = mkOption {
|
ports = mkOption {
|
||||||
type = with types; listOf str;
|
type = with types; listOf str;
|
||||||
|
@ -447,14 +447,14 @@ let
|
||||||
nets = mkOption {
|
nets = mkOption {
|
||||||
type = with types; listOf str;
|
type = with types; listOf str;
|
||||||
description = "Automatically generated";
|
description = "Automatically generated";
|
||||||
default = getHostNets name;
|
default = getHostLinkNetworks hostName name;
|
||||||
};
|
};
|
||||||
vlans = mkOption {
|
vlans = mkOption {
|
||||||
type = with types; listOf int;
|
type = with types; listOf int;
|
||||||
description = "Automatically generated, do not set";
|
description = "Automatically generated, do not set";
|
||||||
default = map (net:
|
default = map (net:
|
||||||
config.site.net.${net}.vlan
|
config.site.net.${net}.vlan
|
||||||
) (getHostNets name);
|
) config.site.hosts.${hostName}.links.${name}.nets;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue