forked from mirrors_public/oddlama_nix-config
refactor: properly modularize repo secret management
This commit is contained in:
parent
88f1ac54b8
commit
d7f69c5baa
25 changed files with 143 additions and 129 deletions
|
@ -82,10 +82,9 @@
|
||||||
|
|
||||||
# The identities that are used to rekey agenix secrets and to
|
# The identities that are used to rekey agenix secrets and to
|
||||||
# decrypt all repository-wide secrets.
|
# decrypt all repository-wide secrets.
|
||||||
secrets = {
|
secretsConfig = {
|
||||||
masterIdentities = [./secrets/yk1-nix-rage.pub];
|
masterIdentities = [./secrets/yk1-nix-rage.pub];
|
||||||
extraEncryptionPubkeys = [./secrets/backup.pub];
|
extraEncryptionPubkeys = [./secrets/backup.pub];
|
||||||
content = import ./nix/secrets.nix inputs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
stateVersion = "23.05";
|
stateVersion = "23.05";
|
||||||
|
@ -112,6 +111,7 @@
|
||||||
(nodeName: nodeAttrs:
|
(nodeName: nodeAttrs:
|
||||||
nixpkgs.lib.mapAttrs'
|
nixpkgs.lib.mapAttrs'
|
||||||
# TODO This is duplicated three times. This is microvm naming #3
|
# TODO This is duplicated three times. This is microvm naming #3
|
||||||
|
# TODO maybe use microvm.vms.<name>.compoundName
|
||||||
(n: nixpkgs.lib.nameValuePair "${nodeName}-${n}")
|
(n: nixpkgs.lib.nameValuePair "${nodeName}-${n}")
|
||||||
(self.colmenaNodes.${nodeName}.config.microvm.vms or {}))
|
(self.colmenaNodes.${nodeName}.config.microvm.vms or {}))
|
||||||
self.colmenaNodes;
|
self.colmenaNodes;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
../../../modules/interface-naming.nix
|
../../../modules/interface-naming.nix
|
||||||
../../../modules/microvms.nix
|
../../../modules/microvms.nix
|
||||||
../../../modules/wireguard.nix
|
../../../modules/wireguard.nix
|
||||||
|
../../../modules/repo.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
home-manager = {
|
home-manager = {
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
nodeName,
|
nodeName,
|
||||||
nodeSecrets,
|
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit
|
inherit
|
||||||
|
@ -78,5 +77,5 @@ in {
|
||||||
systemd.network.enable = true;
|
systemd.network.enable = true;
|
||||||
|
|
||||||
# Rename known network interfaces
|
# Rename known network interfaces
|
||||||
extra.networking.renameInterfacesByMac = lib.mapAttrs (_: v: v.mac) (nodeSecrets.networking.interfaces or {});
|
extra.networking.renameInterfacesByMac = lib.mapAttrs (_: v: v.mac) (config.repo.secrets.local.networking.interfaces or {});
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,10 +177,19 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Define local repo secrets
|
||||||
|
repo.secretFiles = let
|
||||||
|
local = nodePath + "/secrets/local.nix.age";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
global = ../../../secrets/global.nix.age;
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs (nodePath != null && lib.pathExists local) {inherit local;};
|
||||||
|
|
||||||
# Setup secret rekeying parameters
|
# Setup secret rekeying parameters
|
||||||
rekey = {
|
rekey = {
|
||||||
inherit
|
inherit
|
||||||
(inputs.self.secrets)
|
(inputs.self.secretsConfig)
|
||||||
masterIdentities
|
masterIdentities
|
||||||
extraEncryptionPubkeys
|
extraEncryptionPubkeys
|
||||||
;
|
;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./documentation.nix
|
./documentation.nix
|
||||||
./nix.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
environment.enableDebugInfo = true;
|
environment.enableDebugInfo = true;
|
||||||
|
repo.defineNixExtraBuiltins = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
{pkgs, ...}: {
|
|
||||||
# Make sure not to reference the extra-builtins file directly but
|
|
||||||
# at least via its parent folder so it can access relative files.
|
|
||||||
nix.extraOptions = ''
|
|
||||||
plugin-files = ${pkgs.nix-plugins}/lib/nix/plugins
|
|
||||||
extra-builtins-file = ${../../../nix}/extra-builtins.nix
|
|
||||||
'';
|
|
||||||
}
|
|
|
@ -1,10 +1,6 @@
|
||||||
{
|
{config, ...}: {
|
||||||
config,
|
|
||||||
nodeSecrets,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
networking = {
|
networking = {
|
||||||
inherit (nodeSecrets.networking) hostId;
|
inherit (config.repo.secrets.local.networking) hostId;
|
||||||
wireless.iwd.enable = true;
|
wireless.iwd.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,14 +12,14 @@
|
||||||
systemd.network.networks = {
|
systemd.network.networks = {
|
||||||
"10-lan1" = {
|
"10-lan1" = {
|
||||||
DHCP = "yes";
|
DHCP = "yes";
|
||||||
matchConfig.MACAddress = nodeSecrets.networking.interfaces.lan1.mac;
|
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.lan1.mac;
|
||||||
networkConfig.IPv6PrivacyExtensions = "yes";
|
networkConfig.IPv6PrivacyExtensions = "yes";
|
||||||
dhcpV4Config.RouteMetric = 10;
|
dhcpV4Config.RouteMetric = 10;
|
||||||
dhcpV6Config.RouteMetric = 10;
|
dhcpV6Config.RouteMetric = 10;
|
||||||
};
|
};
|
||||||
"10-wlan1" = {
|
"10-wlan1" = {
|
||||||
DHCP = "yes";
|
DHCP = "yes";
|
||||||
matchConfig.MACAddress = nodeSecrets.networking.interfaces.wlan1.mac;
|
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.wlan1.mac;
|
||||||
networkConfig.IPv6PrivacyExtensions = "yes";
|
networkConfig.IPv6PrivacyExtensions = "yes";
|
||||||
dhcpV4Config.RouteMetric = 40;
|
dhcpV4Config.RouteMetric = 40;
|
||||||
dhcpV6Config.RouteMetric = 40;
|
dhcpV6Config.RouteMetric = 40;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
|
config,
|
||||||
lib,
|
lib,
|
||||||
extraLib,
|
extraLib,
|
||||||
nodeSecrets,
|
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
disk = {
|
disk = {
|
||||||
m2-ssd = {
|
m2-ssd = {
|
||||||
type = "disk";
|
type = "disk";
|
||||||
device = "/dev/disk/by-id/${nodeSecrets.disk.m2-ssd}";
|
device = "/dev/disk/by-id/${config.repo.secrets.local.disk.m2-ssd}";
|
||||||
content = with extraLib.disko.gpt; {
|
content = with extraLib.disko.gpt; {
|
||||||
type = "table";
|
type = "table";
|
||||||
format = "gpt";
|
format = "gpt";
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
nodeSecrets,
|
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (config.lib.net) ip cidr;
|
inherit (config.lib.net) ip cidr;
|
||||||
|
@ -9,7 +8,7 @@
|
||||||
lanCidrv4 = "192.168.100.0/24";
|
lanCidrv4 = "192.168.100.0/24";
|
||||||
lanCidrv6 = "fd00::/64";
|
lanCidrv6 = "fd00::/64";
|
||||||
in {
|
in {
|
||||||
networking.hostId = nodeSecrets.networking.hostId;
|
networking.hostId = config.repo.secrets.local.networking.hostId;
|
||||||
|
|
||||||
boot.initrd.systemd.network = {
|
boot.initrd.systemd.network = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -31,7 +30,7 @@ in {
|
||||||
|
|
||||||
systemd.network.networks = {
|
systemd.network.networks = {
|
||||||
"10-lan" = {
|
"10-lan" = {
|
||||||
matchConfig.MACAddress = nodeSecrets.networking.interfaces.lan.mac;
|
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.lan.mac;
|
||||||
# This interface should only be used from attached macvtaps.
|
# This interface should only be used from attached macvtaps.
|
||||||
# So don't acquire a link local address and only wait for
|
# So don't acquire a link local address and only wait for
|
||||||
# this interface to gain a carrier.
|
# this interface to gain a carrier.
|
||||||
|
@ -50,7 +49,7 @@ in {
|
||||||
#];
|
#];
|
||||||
#gateway = [
|
#gateway = [
|
||||||
#];
|
#];
|
||||||
matchConfig.MACAddress = nodeSecrets.networking.interfaces.wan.mac;
|
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.wan.mac;
|
||||||
networkConfig.IPv6PrivacyExtensions = "yes";
|
networkConfig.IPv6PrivacyExtensions = "yes";
|
||||||
linkConfig.RequiredForOnline = "routable";
|
linkConfig.RequiredForOnline = "routable";
|
||||||
};
|
};
|
||||||
|
@ -183,7 +182,7 @@ in {
|
||||||
systemd.services.kea-dhcp4-server.after = ["sys-subsystem-net-devices-lan.device"];
|
systemd.services.kea-dhcp4-server.after = ["sys-subsystem-net-devices-lan.device"];
|
||||||
|
|
||||||
extra.microvms.networking = {
|
extra.microvms.networking = {
|
||||||
baseMac = nodeSecrets.networking.interfaces.lan.mac;
|
baseMac = config.repo.secrets.local.networking.interfaces.lan.mac;
|
||||||
macvtapInterface = "lan";
|
macvtapInterface = "lan";
|
||||||
static = {
|
static = {
|
||||||
baseCidrv4 = lanCidrv4;
|
baseCidrv4 = lanCidrv4;
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
{
|
{config, ...}: {
|
||||||
config,
|
|
||||||
nodeSecrets,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
services.vaultwarden = {
|
services.vaultwarden = {
|
||||||
enable = true;
|
enable = true;
|
||||||
dbBackend = "sqlite";
|
dbBackend = "sqlite";
|
||||||
|
@ -22,7 +18,7 @@
|
||||||
PASSWORD_ITERATIONS = 1000000;
|
PASSWORD_ITERATIONS = 1000000;
|
||||||
INVITATIONS_ALLOWED = true;
|
INVITATIONS_ALLOWED = true;
|
||||||
INVITATION_ORG_NAME = "Vaultwarden";
|
INVITATION_ORG_NAME = "Vaultwarden";
|
||||||
DOMAIN = nodeSecrets.vaultwarden.domain;
|
DOMAIN = config.repo.secrets.local.vaultwarden.domain;
|
||||||
|
|
||||||
SMTP_EMBED_IMAGES = true;
|
SMTP_EMBED_IMAGES = true;
|
||||||
};
|
};
|
||||||
|
@ -59,7 +55,7 @@
|
||||||
keepalive 2;
|
keepalive 2;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
virtualHosts."${nodeSecrets.vaultwarden.domain}" = {
|
virtualHosts."${config.repo.secrets.local.vaultwarden.domain}" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
#enableACME = true;
|
#enableACME = true;
|
||||||
sslCertificate = config.rekey.secrets."selfcert.crt".path;
|
sslCertificate = config.rekey.secrets."selfcert.crt".path;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
nodeSecrets,
|
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
services.esphome = {
|
services.esphome = {
|
||||||
|
@ -24,7 +23,7 @@
|
||||||
keepalive 2;
|
keepalive 2;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
virtualHosts."${nodeSecrets.esphome.domain}" = {
|
virtualHosts."${config.repo.secrets.local.esphome.domain}" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
#enableACME = true;
|
#enableACME = true;
|
||||||
sslCertificate = config.rekey.secrets."selfcert.crt".path;
|
sslCertificate = config.rekey.secrets."selfcert.crt".path;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
nodeSecrets,
|
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
haPort = 8123;
|
haPort = 8123;
|
||||||
|
@ -115,7 +114,7 @@ in {
|
||||||
keepalive 2;
|
keepalive 2;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
virtualHosts."${nodeSecrets.homeassistant.domain}" = {
|
virtualHosts."${config.repo.secrets.local.homeassistant.domain}" = {
|
||||||
serverAliases = ["192.168.1.21"]; # TODO remove later
|
serverAliases = ["192.168.1.21"]; # TODO remove later
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
#enableACME = true;
|
#enableACME = true;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
nodeSecrets,
|
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
imports = [../../modules/hostapd.nix];
|
imports = [../../modules/hostapd.nix];
|
||||||
|
@ -19,7 +18,7 @@
|
||||||
channel = 13; # Automatic Channel Selection (ACS) is unfortunately not implemented for mt7612u.
|
channel = 13; # Automatic Channel Selection (ACS) is unfortunately not implemented for mt7612u.
|
||||||
wifi4.capabilities = ["LDPC" "HT40+" "HT40-" "GF" "SHORT-GI-20" "SHORT-GI-40" "TX-STBC" "RX-STBC1"];
|
wifi4.capabilities = ["LDPC" "HT40+" "HT40-" "GF" "SHORT-GI-20" "SHORT-GI-40" "TX-STBC" "RX-STBC1"];
|
||||||
networks.wlan1 = {
|
networks.wlan1 = {
|
||||||
inherit (nodeSecrets.hostapd) ssid;
|
inherit (config.repo.secrets.local.hostapd) ssid;
|
||||||
macAcl = "allow";
|
macAcl = "allow";
|
||||||
apIsolate = true;
|
apIsolate = true;
|
||||||
authentication = {
|
authentication = {
|
||||||
|
@ -30,7 +29,7 @@
|
||||||
bssid = "00:c0:ca:b1:4f:9f";
|
bssid = "00:c0:ca:b1:4f:9f";
|
||||||
};
|
};
|
||||||
#networks.wlan1-2 = {
|
#networks.wlan1-2 = {
|
||||||
# inherit (nodeSecrets.hostapd) ssid;
|
# inherit (config.repo.secrets.local.hostapd) ssid;
|
||||||
# authentication.mode = "none";
|
# authentication.mode = "none";
|
||||||
# bssid = "02:c0:ca:b1:4f:9f";
|
# bssid = "02:c0:ca:b1:4f:9f";
|
||||||
#};
|
#};
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
nodeSecrets,
|
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (config.lib.net) cidr;
|
inherit (config.lib.net) cidr;
|
||||||
|
@ -9,7 +8,7 @@
|
||||||
net.iot.ipv4cidr = "10.90.0.1/24";
|
net.iot.ipv4cidr = "10.90.0.1/24";
|
||||||
net.iot.ipv6cidr = "fd90::1/64";
|
net.iot.ipv6cidr = "fd90::1/64";
|
||||||
in {
|
in {
|
||||||
networking.hostId = nodeSecrets.networking.hostId;
|
networking.hostId = config.repo.secrets.local.networking.hostId;
|
||||||
|
|
||||||
boot.initrd.systemd.network = {
|
boot.initrd.systemd.network = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -19,13 +18,13 @@ in {
|
||||||
systemd.network.networks = {
|
systemd.network.networks = {
|
||||||
"10-lan1" = {
|
"10-lan1" = {
|
||||||
DHCP = "yes";
|
DHCP = "yes";
|
||||||
matchConfig.MACAddress = nodeSecrets.networking.interfaces.lan1.mac;
|
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.lan1.mac;
|
||||||
networkConfig.IPv6PrivacyExtensions = "yes";
|
networkConfig.IPv6PrivacyExtensions = "yes";
|
||||||
linkConfig.RequiredForOnline = "routable";
|
linkConfig.RequiredForOnline = "routable";
|
||||||
};
|
};
|
||||||
"10-wlan1" = {
|
"10-wlan1" = {
|
||||||
address = [net.iot.ipv4cidr net.iot.ipv6cidr];
|
address = [net.iot.ipv4cidr net.iot.ipv6cidr];
|
||||||
matchConfig.MACAddress = nodeSecrets.networking.interfaces.wlan1.mac;
|
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.wlan1.mac;
|
||||||
linkConfig.RequiredForOnline = "no";
|
linkConfig.RequiredForOnline = "no";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
nodeSecrets,
|
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
rekey.secrets."selfcert.crt" = {
|
rekey.secrets."selfcert.crt" = {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
nodeSecrets,
|
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
rekey.secrets."mosquitto-pw-zigbee2mqtt.yaml" = {
|
rekey.secrets."mosquitto-pw-zigbee2mqtt.yaml" = {
|
||||||
|
@ -39,7 +38,7 @@
|
||||||
keepalive 2;
|
keepalive 2;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
virtualHosts."${nodeSecrets.zigbee2mqtt.domain}" = {
|
virtualHosts."${config.repo.secrets.local.zigbee2mqtt.domain}" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
#enableACME = true;
|
#enableACME = true;
|
||||||
sslCertificate = config.rekey.secrets."selfcert.crt".path;
|
sslCertificate = config.rekey.secrets."selfcert.crt".path;
|
||||||
|
|
93
modules/repo.nix
Normal file
93
modules/repo.nix
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit
|
||||||
|
(lib)
|
||||||
|
assertMsg
|
||||||
|
attrNames
|
||||||
|
literalExpression
|
||||||
|
mapAttrs
|
||||||
|
mkIf
|
||||||
|
mkOption
|
||||||
|
types
|
||||||
|
;
|
||||||
|
|
||||||
|
# If the given expression is a bare set, it will be wrapped in a function,
|
||||||
|
# so that the imported file can always be applied to the inputs, similar to
|
||||||
|
# how modules can be functions or sets.
|
||||||
|
constSet = x:
|
||||||
|
if builtins.isAttrs x
|
||||||
|
then (_: x)
|
||||||
|
else x;
|
||||||
|
|
||||||
|
# Try to access the extra builtin we loaded via nix-plugins.
|
||||||
|
# Throw an error if that doesn't exist.
|
||||||
|
rageImportEncrypted = assert assertMsg (builtins ? extraBuiltins.rageImportEncrypted) "The extra builtin 'rageImportEncrypted' is not available, so repo.secrets cannot be decrypted. Did you forget to use `defineNixExtraBuiltins` or use the appropriate ad-hoc command line arguments?";
|
||||||
|
builtins.extraBuiltins.rageImportEncrypted;
|
||||||
|
|
||||||
|
# This "imports" an encrypted .nix.age file by evaluating the decrypted content.
|
||||||
|
importEncrypted = path:
|
||||||
|
constSet (
|
||||||
|
if builtins.pathExists path
|
||||||
|
then rageImportEncrypted inputs.self.secretsConfig.masterIdentities path
|
||||||
|
else {}
|
||||||
|
);
|
||||||
|
|
||||||
|
cfg = config.repo;
|
||||||
|
in {
|
||||||
|
options.repo = {
|
||||||
|
defineNixExtraBuiltins = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Add nix-plugins and the correct extra-builtin-files definition to this host's
|
||||||
|
nix configuration, so that it can be used to decrypt the secrets in this repository.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
secretFiles = mkOption {
|
||||||
|
default = {};
|
||||||
|
type = types.attrsOf types.path;
|
||||||
|
example = literalExpression "{ local = ./secrets.nix.age; }";
|
||||||
|
description = ''
|
||||||
|
This file manages the origin for this machine's repository-secrets. Anything that is
|
||||||
|
technically not a secret in the classical sense (i.e. that it has to be protected
|
||||||
|
after it has been deployed), but something you want to keep secret from the public;
|
||||||
|
Anything that you wouldn't want people to see on GitHub, but that can live unencrypted
|
||||||
|
on your own devices. Consider it a more ergonomic nix alternative to using git-crypt.
|
||||||
|
|
||||||
|
All of these secrets may (and probably will be) put into the world-readable nix-store
|
||||||
|
on the build and target hosts. You'll most likely want to store personally identifiable
|
||||||
|
information here, such as:
|
||||||
|
- MAC Addreses
|
||||||
|
- Static IP addresses
|
||||||
|
- Your full name (when configuring your users)
|
||||||
|
- Your postal address (when configuring e.g. home-assistant)
|
||||||
|
- ...
|
||||||
|
|
||||||
|
Each path given here must be an age-encrypted .nix file. For each attribute `<name>`,
|
||||||
|
the corresponding file will be decrypted, imported and exposed as {option}`repo.secrets.<name>`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
secrets = mkOption {
|
||||||
|
readOnly = true;
|
||||||
|
default = mapAttrs (_: x: importEncrypted x inputs) cfg.secretFiles;
|
||||||
|
type = types.unspecified;
|
||||||
|
description = "Exposes the loaded repo secrets. This option is read-only.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
# Make sure not to reference the extra-builtins file directly but
|
||||||
|
# at least via its parent folder so it can access relative files.
|
||||||
|
nix.extraOptions = mkIf cfg.defineNixExtraBuiltins ''
|
||||||
|
plugin-files = ${pkgs.nix-plugins}/lib/nix/plugins
|
||||||
|
extra-builtins-file = ${../nix}/extra-builtins.nix
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
|
@ -10,10 +10,10 @@
|
||||||
;
|
;
|
||||||
|
|
||||||
nixosNodes = filterAttrs (_: x: x.type == "nixos") self.hosts;
|
nixosNodes = filterAttrs (_: x: x.type == "nixos") self.hosts;
|
||||||
nodes = mapAttrs (import ./generate-node.nix inputs) nixosNodes;
|
nodes =
|
||||||
generateColmenaNode = nodeName: _: {
|
mapAttrs
|
||||||
inherit (nodes.${nodeName}) imports;
|
(n: v: import ./generate-node.nix inputs n ({config = ../hosts/${n};} // v))
|
||||||
};
|
nixosNodes;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
meta = {
|
meta = {
|
||||||
|
@ -24,4 +24,4 @@ in
|
||||||
nodeSpecialArgs = mapAttrs (_: node: node.specialArgs) nodes;
|
nodeSpecialArgs = mapAttrs (_: node: node.specialArgs) nodes;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// mapAttrs generateColmenaNode nodes
|
// mapAttrs (_: node: {inherit (node) imports;}) nodes
|
||||||
|
|
|
@ -13,23 +13,24 @@
|
||||||
...
|
...
|
||||||
} @ inputs: let
|
} @ inputs: let
|
||||||
inherit (nixpkgs.lib) optionals;
|
inherit (nixpkgs.lib) optionals;
|
||||||
|
pathOrNull = x:
|
||||||
|
if builtins.isPath x
|
||||||
|
then x
|
||||||
|
else null;
|
||||||
in
|
in
|
||||||
nodeName: nodeMeta: let
|
nodeName: nodeMeta: {
|
||||||
nodePath = nodeMeta.config or (../hosts + "/${nodeName}");
|
|
||||||
in {
|
|
||||||
inherit (nodeMeta) system;
|
inherit (nodeMeta) system;
|
||||||
pkgs = self.pkgs.${nodeMeta.system};
|
pkgs = self.pkgs.${nodeMeta.system};
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit (nixpkgs) lib;
|
inherit (nixpkgs) lib;
|
||||||
inherit (self) extraLib nodes stateVersion;
|
inherit (self) extraLib nodes stateVersion;
|
||||||
inherit inputs nodeName nodePath;
|
inherit inputs nodeName;
|
||||||
secrets = self.secrets.content;
|
nodePath = pathOrNull (nodeMeta.config or null);
|
||||||
nodeSecrets = self.secrets.content.nodes.${nodeName} or {};
|
|
||||||
nixos-hardware = nixos-hardware.nixosModules;
|
nixos-hardware = nixos-hardware.nixosModules;
|
||||||
microvm = microvm.nixosModules;
|
microvm = microvm.nixosModules;
|
||||||
};
|
};
|
||||||
imports = [
|
imports = [
|
||||||
nodePath # default module
|
(nodeMeta.config or {})
|
||||||
agenix.nixosModules.default
|
agenix.nixosModules.default
|
||||||
agenix-rekey.nixosModules.default
|
agenix-rekey.nixosModules.default
|
||||||
disko.nixosModules.disko
|
disko.nixosModules.disko
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
# This file manages access to repository-secrets. Anything that is technically
|
|
||||||
# not a secret on your hosts, but something you want to keep secret from the public.
|
|
||||||
# Anything you don't want people to see on GitHub that isn't a password or encrypted
|
|
||||||
# using agenix.
|
|
||||||
#
|
|
||||||
# All of these secrets may (and probably will be) put into the world-readable nix-store
|
|
||||||
# on the build and target hosts. You'll most likely want to store personally identifiable
|
|
||||||
# information here, such as:
|
|
||||||
# - MAC Addreses
|
|
||||||
# - Static IP addresses
|
|
||||||
# - Your full name (when configuring e.g. users)
|
|
||||||
# - Your postal address (when configuring e.g. home-assistant)
|
|
||||||
# - ...
|
|
||||||
{
|
|
||||||
self,
|
|
||||||
nixpkgs,
|
|
||||||
...
|
|
||||||
} @ inputs: let
|
|
||||||
inherit
|
|
||||||
(nixpkgs.lib)
|
|
||||||
attrNames
|
|
||||||
concatMap
|
|
||||||
filterAttrs
|
|
||||||
listToAttrs
|
|
||||||
mapAttrs
|
|
||||||
nameValuePair
|
|
||||||
;
|
|
||||||
# If the given expression is a bare set, it will be wrapped in a function,
|
|
||||||
# so that the imported file can always be applied to the inputs, similar to
|
|
||||||
# how modules can be functions or sets.
|
|
||||||
constSet = x:
|
|
||||||
if builtins.isAttrs x
|
|
||||||
then (_: x)
|
|
||||||
else x;
|
|
||||||
# This "imports" an encrypted .nix.age file
|
|
||||||
importEncrypted = path:
|
|
||||||
constSet (
|
|
||||||
if builtins.pathExists path
|
|
||||||
then builtins.extraBuiltins.rageImportEncrypted self.secrets.masterIdentities path
|
|
||||||
else {}
|
|
||||||
);
|
|
||||||
|
|
||||||
# Secrets for each physical node
|
|
||||||
nodeSecrets = mapAttrs (nodeName: _: importEncrypted ../hosts/${nodeName}/secrets/secrets.nix.age inputs) self.hosts;
|
|
||||||
|
|
||||||
# A list of all nodes that have microvm directories
|
|
||||||
nodesWithMicrovms = builtins.filter (nodeName: builtins.pathExists ../hosts/${nodeName}/microvms) (attrNames self.hosts);
|
|
||||||
# Returns a list of all microvms defined for the given node
|
|
||||||
microvmsFor = nodeName:
|
|
||||||
attrNames (filterAttrs
|
|
||||||
(_: t: t == "directory")
|
|
||||||
(builtins.readDir ../hosts/${nodeName}/microvms));
|
|
||||||
# Returns all defined microvms with name and definition for a given node
|
|
||||||
microvmDefsFor = nodeName:
|
|
||||||
map
|
|
||||||
# TODO This is duplicated three times. This is microvm naming #2
|
|
||||||
(microvmName: nameValuePair "${nodeName}-${microvmName}" ../hosts/${nodeName}/microvms/${microvmName})
|
|
||||||
(microvmsFor nodeName);
|
|
||||||
# A attrset mapping all microvm nodes to its definition folder
|
|
||||||
microvms = listToAttrs (concatMap microvmDefsFor nodesWithMicrovms);
|
|
||||||
# The secrets for each microvm
|
|
||||||
microvmSecrets = mapAttrs (microvmName: microvmPath: importEncrypted (microvmPath + "/secrets/secrets.nix.age") inputs) microvms;
|
|
||||||
in
|
|
||||||
(importEncrypted ../secrets/secrets.nix.age inputs)
|
|
||||||
// {nodes = nodeSecrets // microvmSecrets;}
|
|
|
@ -2,11 +2,10 @@
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
secrets,
|
|
||||||
stateVersion,
|
stateVersion,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (secrets) myuser;
|
inherit (config.repo.secrets.global) myuser;
|
||||||
in {
|
in {
|
||||||
users.groups.${myuser}.gid = config.users.users.${myuser}.uid;
|
users.groups.${myuser}.gid = config.users.users.${myuser}.uid;
|
||||||
users.users.${myuser} = {
|
users.users.${myuser} = {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue