wrtnix/utils.nix

374 lines
14 KiB
Nix

pkgs: let
mkSection = name: config: options:
if builtins.hasAttr name config then
let attr = builtins.getAttr name config; in
if attr != {} then
pkgs.lib.concatStrings (
[ "config ${name}\n" ] ++
(map (o: o attr) options) ++
[ "\n\n" ]
)
else ""
else "";
mkSections = name: config: options:
if builtins.hasAttr name config then
pkgs.lib.concatStrings (
pkgs.lib.attrsets.mapAttrsToList (k: v:
pkgs.lib.concatStrings (
[ "config ${name} '${k}'\n" ] ++
(map (o: o v) options) ++
[ "\n\n" ]
)
) (builtins.getAttr name config)
) else "";
mkSectionsList = name: config: options:
if builtins.hasAttr name config then
pkgs.lib.concatStrings (
map (v:
pkgs.lib.concatStrings (
[ "config ${name}\n" ] ++
(map (o: o v) options) ++
[ "\n\n" ]
)
) (builtins.getAttr name config)
)
else "";
option = name: value: "\toption ${name} '${toString value}'\n";
list = name: value: "\tlist ${name} '${toString value}'\n";
mkOptional = name:
{ config, typeFn }:
if builtins.hasAttr name config then
typeFn { inherit name config; }
else "";
mkMandatory = name:
{ config, typeFn }:
assert pkgs.lib.asserts.assertMsg
(builtins.hasAttr name config)
"missing required attribute '${name}'";
typeFn { inherit name config; };
typeList = optionFn: config: optionFn {
inherit config;
typeFn = { name, config }:
let
attr = builtins.getAttr name config;
type = builtins.typeOf attr;
in
assert pkgs.lib.asserts.assertMsg (type == "list")
"attribute '${name}' expected list, found ${builtins.typeOf attr}";
pkgs.lib.concatStrings (map (v: list name v) attr);
};
typeString = optionFn: config: optionFn {
inherit config;
typeFn = { name, config }:
let
attr = builtins.getAttr name config;
type = builtins.typeOf attr;
in
assert pkgs.lib.asserts.assertMsg (type == "string")
"attribute '${name}' expected string, found ${builtins.typeOf attr}";
option name attr;
};
typeBool = optionFn: config: optionFn {
inherit config;
typeFn = { name, config }:
let
attr = builtins.getAttr name config;
type = builtins.typeOf attr;
in
assert pkgs.lib.asserts.assertMsg (type == "bool")
"attribute '${name}' expected bool, found ${builtins.typeOf attr}";
option name (if attr then "1" else "0");
};
typeFirewall = optionFn: config: optionFn {
inherit config;
typeFn = { name, config }:
let
attr = builtins.getAttr name config;
type = builtins.typeOf attr;
in
assert pkgs.lib.asserts.assertMsg (type == "string")
"attribute '${name}' expected string, found ${builtins.typeOf attr}";
assert pkgs.lib.asserts.assertMsg (
attr == "ACCEPT" || attr == "REJECT" ||
attr == "DROP" || attr == "NOTRACK" ||
attr == "HELPER" || attr == "MARK" ||
attr == "DSCP"
) "attribute '${name}' must be one of ACCEPT, REJECT, DROP, NOTRACK, HELPER, MARK, DSCP";
option name attr;
};
typeInt = optionFn: config: optionFn {
inherit config;
typeFn = { name, config }:
let
attr = builtins.getAttr name config;
type = builtins.typeOf attr;
in
assert pkgs.lib.asserts.assertMsg (type == "int")
"attribute '${name}' expected int, found ${builtins.typeOf attr}";
option name attr;
};
in {
buildConfig = path: let
config = import path;
in {
dhcp = pkgs.lib.concatStrings [
(mkSection "dnsmasq" config.dhcp [
(typeBool (mkOptional "domainneeded"))
(typeBool (mkOptional "boguspriv"))
(typeBool (mkOptional "filterwin2k"))
(typeBool (mkOptional "localise_queries"))
(typeBool (mkOptional "rebind_protection"))
(typeBool (mkOptional "rebind_localhost"))
(typeString (mkOptional "local"))
(typeString (mkOptional "domain"))
(typeBool (mkOptional "expandhosts"))
(typeBool (mkOptional "nonegcache"))
(typeInt (mkOptional "cachesize"))
(typeBool (mkOptional "authoritative"))
(typeBool (mkOptional "readethers"))
(typeString (mkOptional "leasefile"))
(typeString (mkOptional "resolvfile"))
(typeBool (mkOptional "nonwildcard"))
(typeBool (mkOptional "localservice"))
(typeInt (mkOptional "ednspacket_max"))
(typeBool (mkOptional "filter_a"))
(typeBool (mkOptional "filter_aaaa"))
])
(mkSections "dhcp" config.dhcp [
(typeString (mkOptional "interface"))
(typeBool (mkOptional "ignore"))
(typeInt (mkOptional "start"))
(typeInt (mkOptional "limit"))
(typeString (mkOptional "leasetime"))
(typeString (mkOptional "dhcpv4"))
(typeString (mkOptional "dhcpv6"))
(typeString (mkOptional "ra"))
(typeBool (mkOptional "ra_slaac"))
])
(mkSections "odhcpd" config.dhcp [
(typeBool (mkOptional "maindhcp"))
(typeString (mkOptional "leasefile"))
(typeString (mkOptional "leasetrigger"))
(typeInt (mkOptional "loglevel"))
])
];
dropbear = pkgs.lib.concatStrings [
(mkSections "dropbear" config.dropbear [
(typeString (mkOptional "PasswordAuth"))
(typeString (mkOptional "RootPasswordAuth"))
(typeInt (mkOptional "Port"))
(typeString (mkOptional "BannerFile"))
])
];
firewall = pkgs.lib.concatStrings [
(mkSection "defaults" config.firewall [
(typeBool (mkOptional "syn_flood"))
(typeFirewall (mkOptional "input"))
(typeFirewall (mkOptional "output"))
(typeFirewall (mkOptional "forward"))
(typeBool (mkOptional "disable_ipv6"))
])
(mkSectionsList "zone" config.firewall [
(typeString (mkMandatory "name"))
(typeList (mkMandatory "network"))
(typeFirewall (mkOptional "input"))
(typeFirewall (mkOptional "output"))
(typeFirewall (mkOptional "forward"))
(typeBool (mkOptional "masq"))
(typeBool (mkOptional "mtu_fix"))
])
(mkSectionsList "forwarding" config.firewall [
(typeString (mkMandatory "src"))
(typeString (mkMandatory "dest"))
])
(mkSectionsList "rule" config.firewall [
(typeString (mkMandatory "name"))
(typeString (mkOptional "src"))
(typeInt (mkOptional "src_port"))
(typeString (mkMandatory "proto"))
(typeString (mkOptional "dest"))
(typeInt (mkOptional "dest_port"))
(typeFirewall (mkMandatory "target"))
(typeString (mkOptional "family"))
(typeList (mkOptional "icmp_type"))
])
(mkSectionsList "redirect" config.firewall [
(typeString (mkMandatory "name"))
(typeString (mkOptional "src"))
(typeString (mkOptional "src_ip"))
(typeString (mkOptional "src_mac"))
(typeInt (mkOptional "src_port"))
(typeInt (mkOptional "src_dport"))
(typeString (mkOptional "dest_ip"))
(typeInt (mkOptional "dest_port"))
(typeString (mkOptional "proto"))
])
];
network = pkgs.lib.concatStrings [
(mkSections "interface" config.network [
(typeString (mkMandatory "device"))
(typeString (mkMandatory "proto"))
(typeString (mkOptional "ipaddr"))
(typeString (mkOptional "netmask"))
(typeString (mkOptional "gateway"))
(typeString (mkOptional "broadcast"))
(typeString (mkOptional "ip6addr"))
(typeString (mkOptional "ip6gw"))
(typeInt (mkOptional "ip6assign"))
(typeList (mkOptional "dns"))
(typeInt (mkOptional "layer"))
])
(mkSections "globals" config.network [
(typeString (mkOptional "ula_prefix"))
(typeBool (mkOptional "packet_steering"))
])
(mkSectionsList "device" config.network [
(typeString (mkMandatory "name"))
(typeString (mkOptional "macaddr"))
(typeString (mkOptional "type"))
(typeString (mkOptional "ifname"))
(typeList (mkOptional "ports"))
])
];
system = pkgs.lib.concatStrings [
(mkSection "system" config.system [
(typeString (mkOptional "hostname"))
(typeString (mkOptional "description"))
(typeString (mkOptional "notes"))
(typeInt (mkOptional "buffersize"))
(typeInt (mkOptional "conloglevel"))
(typeInt (mkOptional "cronloglevel"))
(typeInt (mkOptional "klogconloglevel"))
(typeInt (mkOptional "log_buffer_size"))
(typeString (mkOptional "log_file"))
(typeString (mkOptional "log_hostname"))
(typeString (mkOptional "log_ip"))
(typeInt (mkOptional "log_port"))
(typeString (mkOptional "log_prefix"))
(typeString (mkOptional "log_proto"))
(typeInt (mkOptional "log_size"))
(typeBool (mkOptional "log_trailer_null"))
(typeString (mkOptional "log_type"))
(typeBool (mkOptional "ttylogin"))
(typeInt (mkOptional "urandom_seed"))
(typeString (mkOptional "timezone"))
(typeString (mkOptional "zonename"))
(typeString (mkOptional "zram_comp_algo"))
(typeInt (mkOptional "zram_size_mb"))
(typeString (mkOptional "compat_version"))
])
(mkSections "timeserver" config.system [
(typeBool (mkOptional "enabled"))
(typeBool (mkOptional "enable_server"))
(typeList (mkMandatory "server"))
])
(mkSections "led" config.system [
(typeString (mkOptional "name"))
(typeString (mkOptional "sysfs"))
(typeBool (mkOptional "default"))
])
];
wireless = pkgs.lib.concatStrings [
(mkSections "wifi-device" config.wireless [
(typeString (mkOptional "type"))
(typeString (mkOptional "phy"))
(typeString (mkOptional "macaddr"))
(typeString (mkOptional "path"))
(typeBool (mkOptional "disabled"))
(typeInt (mkOptional "channel"))
# (typeList (mkOptional "channels"))
(typeString (mkOptional "hwmode"))
(typeString (mkOptional "band"))
(typeString (mkOptional "htmode"))
(typeInt (mkOptional "chanbw"))
(typeString (mkOptional "ht_capab"))
(typeInt (mkOptional "txpower"))
(typeBool (mkOptional "diversity"))
(typeInt (mkOptional "rxantenna"))
(typeInt (mkOptional "txantenna"))
(typeString (mkOptional "country"))
(typeBool (mkOptional "country_ie"))
(typeString (mkOptional "distance"))
(typeInt (mkOptional "beacon_int"))
(typeBool (mkOptional "legacy_rates"))
(typeString (mkOptional "require_mode"))
(typeInt (mkOptional "cell_density"))
# (typeList (mkOptional "basic_rate"))
# (typeList (mkOptional "supported_rates"))
(typeInt (mkOptional "log_level"))
(typeList (mkOptional "hostapd_options"))
])
(mkSections "wifi-iface" config.wireless [
(typeString (mkOptional "ifname"))
(typeString (mkOptional "device"))
(typeString (mkOptional "network"))
(typeString (mkOptional "mode"))
(typeBool (mkOptional "disabled"))
(typeString (mkOptional "ssid"))
(typeString (mkOptional "bssid"))
(typeString (mkOptional "mesh_id"))
(typeBool (mkOptional "hidden"))
(typeBool (mkOptional "isolate"))
(typeBool (mkOptional "doth"))
(typeBool (mkOptional "wmm"))
(typeString (mkOptional "encryption"))
(typeString (mkOptional "key"))
(typeString (mkOptional "key1"))
(typeString (mkOptional "key2"))
(typeString (mkOptional "key3"))
(typeString (mkOptional "key4"))
(typeString (mkOptional "macfilter"))
(typeString (mkOptional "iapp_interface"))
(typeBool (mkOptional "rsn_preauth"))
(typeInt (mkOptional "ieee80211w"))
(typeInt (mkOptional "ieee80211w_max_timeout"))
(typeInt (mkOptional "ieee80211w_retry_timeout"))
(typeBool (mkOptional "sae_require_mfp"))
(typeInt (mkOptional "maxassoc"))
(typeString (mkOptional "macaddr"))
(typeInt (mkOptional "dtim_period"))
(typeBool (mkOptional "short_preamble"))
(typeInt (mkOptional "max_listen_int"))
(typeInt (mkOptional "mcast_rate"))
(typeBool (mkOptional "wds"))
(typeString (mkOptional "owe_transition_ssid"))
(typeString (mkOptional "owe_transition_bssid"))
(typeInt (mkOptional "sae_pwe"))
(typeInt (mkOptional "ocv"))
(typeBool (mkOptional "start_disabled"))
(typeBool (mkOptional "default_disabled"))
(typeList (mkOptional "hostapd_bss_options"))
])
];
uhttpd = pkgs.lib.concatStrings [
(mkSections "uhttpd" config.uhttpd [
(typeBool (mkOptional "redirect_https"))
(typeString (mkOptional "home"))
(typeBool (mkOptional "rfc1918_filter"))
(typeInt (mkOptional "max_requests"))
(typeInt (mkOptional "max_connections"))
(typeString (mkOptional "cert"))
(typeString (mkOptional "key"))
(typeString (mkOptional "cgi_prefix"))
(typeInt (mkOptional "script_timeout"))
(typeInt (mkOptional "network_timeout"))
(typeInt (mkOptional "http_keepalive"))
(typeBool (mkOptional "tcp_keepalive"))
(typeString (mkOptional "ubus_prefix"))
])
(mkSections "cert" config.uhttpd [
(typeInt (mkOptional "days"))
(typeString (mkOptional "key_type"))
(typeInt (mkOptional "bits"))
(typeString (mkOptional "ec_curve"))
(typeString (mkOptional "country"))
(typeString (mkOptional "state"))
(typeString (mkOptional "location"))
(typeString (mkOptional "commonname"))
])
];
};
}