difftreelog
feat shared secrets expected owners
in: trunk
7 files changed
crates/nixlike/Cargo.tomldiffbeforeafterboth--- a/crates/nixlike/Cargo.toml
+++ b/crates/nixlike/Cargo.toml
@@ -4,7 +4,7 @@
edition = "2021"
[dependencies]
-dprint-core = "0.50.0"
+dprint-core = "0.51.0"
linked-hash-map = "0.5.4"
peg = "0.8.0"
serde = "1.0.130"
lib/default.nixdiffbeforeafterboth--- a/lib/default.nix
+++ b/lib/default.nix
@@ -1,47 +1,56 @@
{ flake-utils }: {
fleetConfiguration = { data, nixpkgs, hosts, ... }@allConfig:
let
+ hostNames = nixpkgs.lib.attrNames hosts;
config = builtins.removeAttrs allConfig [ "nixpkgs" "data" ];
fleetLib = import ./fleetLib.nix {
- inherit nixpkgs hosts;
+ inherit nixpkgs hostNames;
};
in
- nixpkgs.lib.genAttrs flake-utils.lib.defaultSystems (system: rec {
- root = nixpkgs.lib.evalModules {
- modules = (import ../modules/fleet/_modules.nix) ++ [ config data ];
- specialArgs = {
- inherit nixpkgs;
- fleet = fleetLib;
+ nixpkgs.lib.genAttrs flake-utils.lib.defaultSystems (system:
+ let
+ root = nixpkgs.lib.evalModules {
+ modules = (import ../modules/fleet/_modules.nix) ++ [ config data ];
+ specialArgs = {
+ inherit nixpkgs fleetLib;
+ };
};
- };
- configuredHosts = root.config.hosts;
- configuredSecrets = root.config.secrets;
- configuredSystems = nixpkgs.lib.listToAttrs (
- map
- (
- name: {
- inherit name;
- value = nixpkgs.lib.nixosSystem {
- system = configuredHosts.${name}.system;
- modules = configuredHosts.${name}.modules ++ (
- if configuredHosts.${name}.system == "aarch64-linux" then [ (nixpkgs + "/nixos/modules/installer/sd-card/sd-image-aarch64-installer.nix") ]
- else [ ]
- ) ++ [
- ({ ... }: {
- nixpkgs.system = system;
- nixpkgs.localSystem.system = system;
- nixpkgs.crossSystem = if system == configuredHosts.${name}.system then null else {
- system = configuredHosts.${name}.system;
- };
- })
- ];
- specialArgs = {
- fleet = fleetLib.hostsToAttrs (host: configuredSystems.${host}.config);
+ failedAssertions = map (x: x.message) (nixpkgs.lib.filter (x: !x.assertion) root.config.assertions);
+ rootAssertWarn =
+ if failedAssertions != [ ]
+ then throw "Failed assertions:\n${nixpkgs.lib.concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}"
+ else nixpkgs.lib.showWarnings root.config.warnings root;
+ in
+ rec {
+ configuredHosts = rootAssertWarn.config.hosts;
+ configuredSecrets = rootAssertWarn.config.secrets;
+ configuredSystems = nixpkgs.lib.listToAttrs (
+ map
+ (
+ name: {
+ inherit name;
+ value = nixpkgs.lib.nixosSystem {
+ system = configuredHosts.${name}.system;
+ modules = configuredHosts.${name}.modules ++ (
+ if configuredHosts.${name}.system == "aarch64-linux" then [ (nixpkgs + "/nixos/modules/installer/sd-card/sd-image-aarch64-installer.nix") ]
+ else [ ]
+ ) ++ [
+ ({ ... }: {
+ nixpkgs.system = system;
+ nixpkgs.localSystem.system = system;
+ nixpkgs.crossSystem = if system == configuredHosts.${name}.system then null else {
+ system = configuredHosts.${name}.system;
+ };
+ })
+ ];
+ specialArgs = {
+ inherit fleetLib;
+ fleet = fleetLib.hostsToAttrs (host: configuredSystems.${host}.config);
+ };
};
- };
- }
- )
- (builtins.attrNames root.config.hosts)
- ); #nixpkgs.lib.nixosSystem {}
- });
+ }
+ )
+ (builtins.attrNames rootAssertWarn.config.hosts)
+ ); #nixpkgs.lib.nixosSystem {}
+ });
}
lib/fleetLib.nixdiffbeforeafterboth1# Shared functions for fleet configuration, available as `fleet` module argument2{ nixpkgs, hosts }: with nixpkgs.lib; rec {3 # Modules can't register hosts because of infinite recursion4 hostNames = attrNames hosts;5 hostsToAttrs = f: listToAttrs (6 map (name: { inherit name; value = f name; }) hostNames7 );8 hostsCartesian = remove null (9 unique (10 crossLists11 (12 a: b:13 if a == b then14 null15 else16 hostsPair a b17 ) [ hostNames hostNames ]18 )19 );20 hostsPair = this: other:21 let22 sorted = sort (a: b: a < b) [ this other ];23 in24 {25 a = elemAt sorted 0;26 b = elemAt sorted 1;27 };28}1# Shared functions for fleet configuration, available as `fleet` module argument2{ nixpkgs, hostNames }: with nixpkgs.lib; rec {3 hostsToAttrs = f: listToAttrs (4 map (name: { inherit name; value = f name; }) hostNames5 );6 hostsCartesian = remove null (7 unique (8 crossLists9 (10 a: b:11 if a == b then12 null13 else14 hostsPair a b15 ) [ hostNames hostNames ]16 )17 );18 hostsPair = this: other:19 let20 sorted = sort (a: b: a < b) [ this other ];21 in22 {23 a = elemAt sorted 0;24 b = elemAt sorted 1;25 };26 hostPairName = this: other:27 if this < other then "${this}-${other}"28 else "${other}-${this}";29}modules/fleet/_modules.nixdiffbeforeafterboth--- a/modules/fleet/_modules.nix
+++ b/modules/fleet/_modules.nix
@@ -1,4 +1,5 @@
[
+ ./assertions.nix
./meta.nix
./secrets.nix
]
modules/fleet/assertions.nixdiffbeforeafterboth--- /dev/null
+++ b/modules/fleet/assertions.nix
@@ -0,0 +1,34 @@
+{ lib, ... }:
+
+with lib;
+
+{
+
+ options = {
+
+ assertions = mkOption {
+ type = types.listOf types.unspecified;
+ internal = true;
+ default = [ ];
+ example = [{ assertion = false; message = "you can't enable this for that reason"; }];
+ description = ''
+ This option allows modules to express conditions that must
+ hold for the evaluation of the system configuration to
+ succeed, along with associated error messages for the user.
+ '';
+ };
+
+ warnings = mkOption {
+ internal = true;
+ default = [ ];
+ type = types.listOf types.str;
+ example = [ "The `foo' service is deprecated and will go away soon!" ];
+ description = ''
+ This option allows modules to show warnings to users during
+ the evaluation of the system configuration.
+ '';
+ };
+
+ };
+ # impl of assertions is in <fleet/lib/default.nix>
+}
modules/fleet/meta.nixdiffbeforeafterboth--- a/modules/fleet/meta.nix
+++ b/modules/fleet/meta.nix
@@ -1,4 +1,4 @@
-{ lib, fleet, config, ... }: with lib;
+{ lib, fleetLib, config, ... }: with lib;
let
host = with types; {
options = {
@@ -42,7 +42,7 @@
};
};
config = {
- hosts = fleet.hostsToAttrs (host: {
+ hosts = fleetLib.hostsToAttrs (host: {
modules = config.globalModules;
});
globalModules = import ../../nixos/modules/module-list.nix;
modules/fleet/secrets.nixdiffbeforeafterboth--- a/modules/fleet/secrets.nix
+++ b/modules/fleet/secrets.nix
@@ -1,14 +1,23 @@
-{ lib, fleet, config, ... }: with lib;
+{ lib, fleetLib, config, ... }: with lib; with fleetLib;
let
sharedSecret = with types; {
options = {
owners = mkOption {
type = listOf str;
description = ''
+ For which owners this secret is currently encrypted,
+ if not matches expectedOwners - then this secret is considered outdated, and
+ should be regenerated/reencrypted
+ '';
+ };
+ expectedOwners = mkOption {
+ type = listOf str;
+ description = ''
List of hosts to encrypt secret for
Secrets would be decrypted and stored to /run/secrets/$\{name} on owners
'';
+ default = [ ];
};
generator = mkOption {
type = package;
@@ -67,7 +76,13 @@
description = "Host secrets";
};
};
- config = with fleet; {
+ config = {
+ assertions = mapAttrsToList
+ (name: secret: {
+ assertion = builtins.sort (a: b: a < b) secret.owners == builtins.sort (a: b: a < b) secret.expectedOwners;
+ message = "Shared secret ${name} is expected to be encrypted for ${builtins.toJSON secret.expectedOwners}, but it is encrypted for ${builtins.toJSON secret.owners}";
+ })
+ config.sharedSecrets;
hosts = hostsToAttrs (host: {
modules =
let