feat: clean up the repo

This commit is contained in:
Kat Inskip 2023-04-29 12:00:58 -07:00
parent bc9c310c77
commit f6ec9f37eb
Signed by: kat
GPG key ID: 465E64DECEA8CF0F
249 changed files with 804 additions and 13048 deletions

View file

@ -1,84 +0,0 @@
{ tf, target, name, meta, config, lib, ... }:
/*
This module:
* aliases <hostname>.system.build.toplevel to <hostname>.deploy.system for ease of use.
* marries meta config to NixOS configs for each host.
* provides in-scope TF config in NixOS and home-manager, instead of only as a part of meta config.
*/
with lib;
let
cfg = config.deploy;
unmergedValues = types.mkOptionType {
name = "unmergedValues";
merge = loc: defs: map (def: def.value) defs;
};
in
{
options.deploy = {
targetName = mkOption {
type = types.nullOr types.str;
default = null;
};
system = mkOption {
type = types.unspecified;
readOnly = true;
};
};
options.deploy.tf = mkOption {
type = types.submodule {
inherit (unmerged) freeformType;
options = {
import = mkOption {
type = types.attrsOf types.unspecified;
default = [ ];
};
imports = mkOption {
type = types.listOf types.str;
description = "Other targets to depend on";
default = [ ];
};
attrs = mkOption {
type = types.listOf types.str;
default = [ ];
};
out.set = mkOption { type = types.unspecified; };
};
};
};
config = {
deploy = {
system = config.system.build.toplevel;
targetName = let targetsList = attrNames (filterAttrs (_: target: target.enable && elem name target.nodeNames) meta.deploy.targets); in
if (builtins.length targetsList == 0) then null
else lib.warnIf (builtins.length targetsList > 1) "The host ${name} is assigned to several targets: ${concatMapStrings (x: "${x},") targetsList}." (head targetsList);
};
deploy.tf = mkMerge (singleton
(lib.mkIf (config.deploy.targetName != null) {
attrs = [ "import" "imports" "out" "attrs" ];
import = genAttrs cfg.tf.imports (target: meta.deploy.targets.${target}.tf);
out.set = removeAttrs cfg.tf cfg.tf.attrs;
deploy.systems.${config.networking.hostName} =
with tf.resources; {
isRemote =
(config.networking.hostName != builtins.getEnv "HOME_HOSTNAME");
nixosConfig = config;
connection = tf.resources.${config.networking.hostName}.connection.set;
triggers.copy.${config.networking.hostName} =
tf.resources.${config.networking.hostName}.refAttr "id";
triggers.secrets.${config.networking.hostName} =
tf.resources.${config.networking.hostName}.refAttr "id";
};
}) ++ mapAttrsToList
(_: user:
mapAttrs (_: mkMerge) user.deploy.tf.out.set)
config.home-manager.users);
_module.args.target = mapNullable (targetName: meta.deploy.targets.${targetName}) cfg.targetName;
_module.args.tf = mapNullable (target: target.tf) target;
};
}

View file

@ -1,14 +0,0 @@
{ config, lib, ... }: with lib; {
options.hardware.displays = mkOption {
type = with types; attrsOf (submodule ({ config, ... }: {
options = {
pos = mkOption {
type = types.str;
};
res = mkOption {
type = types.str;
};
};
}));
};
}

View file

@ -1,391 +1,26 @@
{ config, lib, tf, pkgs, meta, ... }: with lib; {
imports = with meta; [
nixos.sops
];
options = let
nixos = config;
in {
domains = mkOption {
default = {};
type = with types; attrsOf (submodule ({ name, config, ... }: {
options = {
host = mkOption {
type = nullOr str;
default = nixos.networking.hostName;
};
owner = mkOption {
type = str;
default = "nginx";
};
group = mkOption {
type = str;
default = "domain-auth";
};
network = mkOption {
type = unspecified;
default = "internet";
};
type = mkOption {
type = types.enum [
"ipv4"
"ipv6"
"both"
"cname"
];
};
create_cert = mkOption {
type = bool;
default = true;
};
domain = mkOption {
type = nullOr str;
default = "${nixos.networking.hostName}${if config.prefix != null then ".${config.prefix}" else ""}";
};
cname = mkOption {
type = nullOr str;
default = "${config.domain}.${config.zone}";
};
prefix = mkOption {
type = nullOr str;
default = null;
};
uqdn = mkOption {
type = nullOr str;
default = (if config.domain == "@" then (removeSuffix "." config.zone) else (removeSuffix "." config.target));
};
zone = mkOption {
type = nullOr str;
default = "kittywit.ch.";
};
key_path = mkOption {
type = nullOr str;
default = if config.create_cert then nixos.secrets.files."${lib.removeSuffix "." config.cname}-key".path else null;
};
cert_path = mkOption {
type = nullOr str;
default = if config.create_cert then nixos.secrets.files."${lib.removeSuffix "." config.cname}-cert".path else null;
};
target = mkOption {
type = nullOr str;
default = if (config.type == "cname" && config.host != nixos.networking.hostName) then
meta.network.nodes.nixos.${config.host}.networks.${config.network}.target
else "${if config.domain == null then "" else "${config.domain}."}${config.zone}";
};
};
}));
};
networks = let
nixos = config;
in mkOption {
default = { };
type = with types; attrsOf (submodule ({ name, config, options, ... }: let
portRangeModule = { config, ... }: {
options = {
from = mkOption {
type = types.port;
};
to = mkOption {
type = types.port;
default = config.from;
};
/*isRange = mkOption {
type = types.bool;
default = assert config.to >= config.from; config.from != config.to;
readOnly = true;
};*/
};
};
portRangeType = types.submodule portRangeModule;
convToPort = value: if isInt value
then { from = value; }
else assert length value == 2; { from = elemAt value 0; to = elemAt value 1; };
portType = coercedTo (oneOf [ int (listOf int) ]) convToPort portRangeType;
in {
options = with types; {
interfaces = mkOption {
description = "Interfaces this network operates upon.";
type = listOf str;
default = [];
};
tcp = mkOption {
description = "Port numbers or ranges to allow TCP traffic outbound.";
type = listOf portType;
default = [];
};
udp = mkOption {
description = "Port numbers or ranges to allow UDP traffic outbound.";
type = listOf portType;
default = [];
};
ip = mkOption {
description = "The machine's IPv4 address on the network, if it has one.";
type = unspecified;
default = hostname: class: if hostname != nixos.networking.hostName then
if class == 6 then
config.ipv6
else if class == 4 then
config.ipv4
else throw "${nixos.networking.hostName}: IP for ${hostname} of ${class} is invalid."
else
if class == 6 then
config.ipv6
else if class == 4 then
config.ipv4
else throw "${nixos.networking.hostName}: IP for ${hostname} of ${class} is invalid.";
};
ipv4 = mkOption {
description = "The machine's IPv4 address on the network, if it has one.";
type = nullOr str;
};
ipv6 = mkOption {
description = "The machine's IPv6 address on the network, if it has one.";
type = nullOr str;
};
ipv4_defined = mkOption {
type = types.bool;
default = options.ipv4.isDefined;
};
ipv6_defined = mkOption {
type = types.bool;
default = options.ipv6.isDefined;
};
create_domain = mkOption {
type = bool;
default = config.extra_domains != [];
};
create_cert = mkOption {
type = bool;
default = config.extra_domains != [];
};
extra_domains = mkOption {
type = listOf str;
description = "Domains to add to the certificate generated for this network.";
default = [];
};
key_path = mkOption {
type = nullOr str;
default = if config.create_cert && config.interfaces != [] then nixos.secrets.files."${lib.removeSuffix "." config.target}-key".path else null;
};
cert_path = mkOption {
type = nullOr str;
default = if config.create_cert && config.interfaces != [] then nixos.secrets.files."${lib.removeSuffix "." config.target}-cert".path else null;
};
domain = mkOption {
type = nullOr str;
default = "${nixos.networking.hostName}${if config.prefix != null then ".${config.prefix}" else ""}";
};
prefix = mkOption {
type = nullOr str;
default = null;
};
zone = mkOption {
type = nullOr str;
default = "kittywit.ch.";
};
uqdn = mkOption {
type = nullOr str;
default = (if config.domain == "@" then (removeSuffix "." config.zone) else (removeSuffix "." config.target));
};
target = mkOption {
type = nullOr str;
default = "${config.domain}.${config.zone}";
};
};
}));
};
{
config,
lib,
pkgs,
meta,
...
}:
with lib; {
options.deploy.system = mkOption {
type = types.unspecified;
readOnly = true;
};
config = let
sane_networks = lib.filterAttrs (network: settings: settings.interfaces != []) config.networks;
in {
networks = {
internet = {
zone = mkDefault "kittywit.ch.";
create_domain = true;
};
chitei = {
zone = mkDefault "kittywit.ch.";
create_domain = false;
};
gensokyo = {
zone = mkDefault "gensokyo.zone.";
create_domain = true;
};
tailscale = mkMerge [
(mkIf tf.state.enable {
ipv4 = mkForce meta.tailnet.${config.networking.hostName}.ipv4 or null;
ipv6 = mkForce meta.tailnet.${config.networking.hostName}.ipv6 or null;
})
{
ipv4 = mkDefault "wawawawaawa";
ipv6 = mkDefault "awawawawawa";
interfaces = singleton "tailscale0";
zone = "inskip.me.";
create_domain = true;
create_cert = true;
}
];
};
config = {
deploy.system = config.system.build.toplevel;
networking.domain = "inskip.me";
deploy.tf = {
dns.records = let
# Families of address to create domains for
address_families = [ "ipv4" "ipv6" ];
domains = config.domains;
# Merge the result of a map upon address_families to mapAttrs'
domains' = map (family: mapAttrs' (name: settings: let
network = if settings.host != config.networking.hostName then
meta.network.nodes.nixos.${settings.host}.networks.${settings.network}
else sane_networks.${settings.network};
in nameValuePair "${settings.network}-${if settings.type == "both" || settings.type == family then family else settings.type}-${if settings.domain == "@" then "root" else settings.domain}-${settings.zone}" ({
inherit (settings) zone;
enable = mkDefault false;
} // optionalAttrs (settings.domain != null && settings.domain != "" && settings.domain != "@") {
inherit (settings) domain;
} // optionalAttrs (settings.domain == null || settings.domain == "" || settings.domain == "@") {
enable = mkForce true;
} // (optionalAttrs (settings.type == "cname" && family == "ipv4") {
cname = { inherit (network) target; };
enable = mkForce true;
}) // (optionalAttrs (network.ipv6_defined && family == "ipv6" && (settings.type == "both" || settings.type == family)) {
aaaa.address = network.ipv6;
enable = mkForce network.ipv6_defined;
})
// (optionalAttrs (!network.ipv4_defined && !network.ipv6_defined) {
a.address = "127.0.0.1";
enable = mkForce false;
}) // (optionalAttrs (network.ipv4_defined && family == "ipv4" && (settings.type == "both" || settings.type == family)) {
a.address = network.ipv4;
enable = mkForce network.ipv4_defined;
}))) domains) address_families;
networks = sane_networks;
# Networks to actually create domains for
networks' = filterAttrs (_: settings: settings.create_domain) networks;
# Extra domains to automatically be cnamed
extraDomainedNetworks = filterAttrs (_: settings: settings.extra_domains != []) networks';
extraDomains = listToAttrs (concatLists (mapAttrsToList (network: settings:
map (domain: let
split_domain = splitString "." domain;
isRoot = (length split_domain) <= 2;
in nameValuePair "${network}-cname-${if isRoot then "root" else elemAt split_domain ((length split_domain) - 2)}-${concatStringsSep "." (sublist (length split_domain - 2) (length split_domain) split_domain)}." {
zone = if isRoot then "${domain}." else "${concatStringsSep "." (sublist ((length split_domain) - 2) (length split_domain) split_domain)}.";
enable = !isRoot;
domain = if isRoot then "@"
else elemAt split_domain (length split_domain - 2);
cname = { inherit (settings) target; };
}) settings.extra_domains) extraDomainedNetworks));
# Merge the result of a map upon address_families to mapAttrs'
networks'' = map (family: mapAttrs' (network: settings:
nameValuePair "${network}-${family}-${settings.domain}-${settings.zone}" ({
inherit (settings) zone domain;
} // (if family == "ipv6" then {
aaaa.address = settings.ipv6;
enable = mkForce settings.ipv6_defined;
} else {
enable = mkForce settings.ipv4_defined;
a.address = settings.ipv4;
})
)) networks') address_families;
in mkMerge (if tf.state.enable then (networks'' ++ domains' ++ [ extraDomains ]) else []);
acme = let
home = meta.deploy.targets.home.tf;
in {
certs = let
nvP = network: settings: nameValuePair settings.uqdn {
keyType = "4096";
dnsNames = [ settings.uqdn ] ++ (lib.optionals (settings ? extra_domains) settings.extra_domains);
};
network_certs = mapAttrs' nvP (filterAttrs (network: settings: settings.create_cert) sane_networks);
domain_certs = mapAttrs' nvP (filterAttrs (network: settings: settings.create_cert) config.domains);
in domain_certs // network_certs;
};
variables = {
tailscale-authkey.export = true;
tailscale-apikey = {
value.shellCommand = "${meta.secrets.command} secrets/tailscale -f api_key";
sensitive = true;
export = true;
};
};
providers.tailscale = {
inputs = {
api_key = tf.variables.tailscale-apikey.ref;
tailnet = "inskip.me";
};
};
resources.tailnet_device_key = {
provider = "tailscale";
type = "device_key";
inputs = {
device_id = meta.tailnet.${config.networking.hostName}.id;
key_expiry_disabled = true;
};
};
resources.tailnet_key = {
provider = "tailscale";
type = "tailnet_key";
inputs = {
reusable = false;
ephemeral = false;
preauthorized = true;
};
};
};
sops.secrets.tailscale-key = { };
services.nginx.virtualHosts = let
networkVirtualHosts = concatLists (mapAttrsToList (network: settings: map(domain: nameValuePair (if domain != "@" then domain else settings.zone) {
}) ([ settings.uqdn ] ++ settings.extra_domains)) (filterAttrs (_: settings: settings.create_cert) sane_networks));
domainVirtualHosts = (filterAttrs (network: settings: settings.create_cert) config.domains);
domainVirtualHosts' = (mapAttrsToList (network: settings: let
in nameValuePair settings.uqdn {
}) domainVirtualHosts);
in listToAttrs (networkVirtualHosts ++ (lib.optionals config.services.nginx.enable domainVirtualHosts'));
users.groups.domain-auth = {
gid = 10600;
};
networking.firewall = {
interfaces = mkMerge (mapAttrsToList (network: settings:
genAttrs settings.interfaces (_: { allowedTCPPortRanges = settings.tcp; allowedUDPPortRanges = settings.udp; })
) (removeAttrs sane_networks ["tailscale"]));
trustedInterfaces = [ "tailscale0" ];
allowedTCPPorts = [ 5200 ];
allowedUDPPorts = [ config.services.tailscale.port ];
trustedInterfaces = ["tailscale0"];
allowedTCPPorts = [5200];
allowedUDPPorts = [config.services.tailscale.port];
};
services.tailscale.enable = true;
systemd.services.tailscale-autoconnect = {
description = "Automatic connection to Tailscale";
# make sure tailscale is running before trying to connect to tailscale
after = [ "network-pre.target" "tailscale.service" ];
wants = [ "network-pre.target" "tailscale.service" ];
wantedBy = [ "multi-user.target" ];
# set this service as a oneshot job
serviceConfig.Type = "oneshot";
# have the job run this shell script
script = with pkgs; ''
# wait for tailscaled to settle
sleep 2
# check if we are already authenticated to tailscale
status="$(${tailscale}/bin/tailscale status -json | ${jq}/bin/jq -r .BackendState)"
if [ $status = "Running" ]; then # if so, then do nothing
exit 0
fi
# otherwise authenticate with tailscale
# to-do: --advertise-exit-node
${tailscale}/bin/tailscale up -authkey $(cat ${config.sops.secrets.tailscale-key.path})
'';
};
};
}

View file

@ -1,69 +0,0 @@
{ config, lib, pkgs, tf, ... }: let
inherit (lib.types) unspecified isType;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf;
inherit (lib.attrsets) mapAttrs' nameValuePair mapAttrsToList;
inherit (lib.strings) concatStringsSep;
cfg = config.services.pounce;
in {
options.services.pounce = {
enable = mkEnableOption "Pounce BNC";
servers = mkOption {
type = unspecified;
default = {};
};
};
config = mkIf (cfg.enable) {
#services.pounce.servers = builtins.fromJSON tf.variables."pounce-config".import;
secrets = {
variables = (mapAttrs' (server: config:
nameValuePair "pounce-${server}-cert" {
path = "gensokyo/pounce";
field = "${server}-cert";
}
) cfg.servers) // (mapAttrs' (server: config:
nameValuePair "pounce-${server}-password" {
path = "gensokyo/pounce";
field = "${server}-password";
}
) cfg.servers) // {
"pounce-config" = {
path = "gensokyo/pounce";
field = "notes";
};
};
files = (mapAttrs' (server: config:
nameValuePair "pounce-${server}-config" {
text = concatStringsSep "\n" (mapAttrsToList (key: value: if (builtins.typeOf value == "bool") then "${key}"
else if (builtins.typeOf value == "int") then "${key} = ${builtins.toString value}"
else if (builtins.typeOf value == "list") then "${key} = ${concatStringsSep "," value}" else "${key} = ${value}") config);
owner = "pounce";
group = "pounce";
}
) cfg.servers) // (mapAttrs' (server: config:
nameValuePair "pounce-${server}-cert" {
text = tf.variables."pounce-${server}-cert".ref;
owner = "pounce";
group = "domain-auth";
}
) cfg.servers);
};
users.users.pounce = {
uid = 1501;
isSystemUser = true;
group = "domain-auth";
};
systemd.services = mapAttrs' (name: text: nameValuePair "pounce-${name}" {
serviceConfig = {
Type = "simple";
Restart = "always";
ExecStart = "${pkgs.pounce}/bin/pounce ${config.secrets.file."pounce-${name}-config".path}";
WorkingDirectory = "/var/lib/pounce";
User = "pounce";
Group = "domain-auth";
};
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
}) cfg.servers;
};
}

View file

@ -1,13 +0,0 @@
{ config, lib, meta, ... }: with lib; {
config = mkIf (config.secrets.variables != { }) {
deploy.tf.variables = mapAttrs'
(name: content:
nameValuePair name ({
value.shellCommand = "${meta.secrets.command} ${content.path}" + optionalString (content.field != "") " -f ${content.field}";
type = "string";
sensitive = true;
})
)
config.secrets.variables;
};
}

View file

@ -1,77 +0,0 @@
{ config, lib, pkgs, meta, tf, ... }: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.attrsets) mapAttrs filterAttrs mapAttrsToList attrValues;
inherit (lib.lists) concatLists;
inherit (lib.types) attrsOf listOf str;
cfg = config.storage;
in {
options.storage = {
enable = mkEnableOption "nixfiles storage primitives";
replica = mkEnableOption "full replication of our volumes onto a node";
defaultBrick = mkEnableOption "naively create a default brick for this node";
bricks = mkOption {
type = attrsOf str;
default = if cfg.defaultBrick then {
default = "/export/default/brick";
} else {};
description = "the brick locations used by glusterfs";
};
replicas = mkOption {
type = listOf str;
default = let
replicaNodes = filterAttrs (_: node: node.storage.replica) config.network.nodes.nixos;
in concatLists (mapAttrsToList (_: node: map (brick: "${node.networks.tailscale.uqdn}:${brick}" (attrValues node.storage.bricks)) replicaNodes));
};
services = mkOption {
type = listOf str;
default = let
filteredServices = removeAttrs config.services [
"chronos" "beegfs" "beegfsEnable" "bird"
"bird6" "bitwarden_rs" "buildkite-agent" "cgmanager"
"codimd" "couchpotato" "cryptpad" "dd-agent"
"deepin" "dnscrypt-proxy" "flashpolicyd" "dhcpd"
"foldingAtHome" "fourStore" "fourStoreEndpoint" "fprot"
"frab" "geoip-updater" "gogoclient" "hbase"
"iodined" "kippo" "localtime" "mailpile"
"marathon" "mathics" "meguca" "mesos"
"mingetty" "moinmoin" "mwlib" "nixosManual"
"openfire" "openvpn" "osquery" "paperless-ng"
"piwik" "plexpy" "prey" "prometheus2"
"quagga" "racoon" "railcar" "redis"
"riak" "rmilter" "seeks" "shellinabox"
"ssmtp" "venus" "virtuoso" "vmwareGuest"
"wakeonlan" "winstone" "nginx"
];
#enabledServices = filterAttrs (_: settings: (settings ? enable) && settings.enable) filteredServices;
enabledServices = filterAttrs (_: service: service ? serviceConfig.RuntimeDirectory) config.systemd.services;
serviceDirs = mapAttrsToList (service: _: service) enabledServices;
in serviceDirs;
};
};
config = mkMerge [
(mkIf false {
environment.systemPackages = [ pkgs.glusterfs ];
services.glusterfs = {
enable = true;
tlsSettings = {
tlsKeyPath = config.networks.tailscale.key_path;
tlsPem = config.networks.tailscale.cert_path;
};
};
deploy.tf = {
};
})
(mkIf cfg.defaultBrick {
system.activationScripts.nixfiles-storage-defaultbrick.text = ''
mkdir -p /export/default/brick
'';
})
(mkIf cfg.replica {
deploy.tf = {
};
})
];
}