Skip to content

Commit 53503ce

Browse files
committed
feat: shared secrets expected owners
Signed-off-by: Yaroslav Bolyukin <[email protected]>
1 parent 144b321 commit 53503ce

File tree

7 files changed

+105
-45
lines changed

7 files changed

+105
-45
lines changed

crates/nixlike/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7-
dprint-core = "0.50.0"
7+
dprint-core = "0.51.0"
88
linked-hash-map = "0.5.4"
99
peg = "0.8.0"
1010
serde = "1.0.130"

lib/default.nix

+46-37
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,56 @@
11
{ flake-utils }: {
22
fleetConfiguration = { data, nixpkgs, hosts, ... }@allConfig:
33
let
4+
hostNames = nixpkgs.lib.attrNames hosts;
45
config = builtins.removeAttrs allConfig [ "nixpkgs" "data" ];
56
fleetLib = import ./fleetLib.nix {
6-
inherit nixpkgs hosts;
7+
inherit nixpkgs hostNames;
78
};
89
in
9-
nixpkgs.lib.genAttrs flake-utils.lib.defaultSystems (system: rec {
10-
root = nixpkgs.lib.evalModules {
11-
modules = (import ../modules/fleet/_modules.nix) ++ [ config data ];
12-
specialArgs = {
13-
inherit nixpkgs;
14-
fleet = fleetLib;
10+
nixpkgs.lib.genAttrs flake-utils.lib.defaultSystems (system:
11+
let
12+
root = nixpkgs.lib.evalModules {
13+
modules = (import ../modules/fleet/_modules.nix) ++ [ config data ];
14+
specialArgs = {
15+
inherit nixpkgs fleetLib;
16+
};
1517
};
16-
};
17-
configuredHosts = root.config.hosts;
18-
configuredSecrets = root.config.secrets;
19-
configuredSystems = nixpkgs.lib.listToAttrs (
20-
map
21-
(
22-
name: {
23-
inherit name;
24-
value = nixpkgs.lib.nixosSystem {
25-
system = configuredHosts.${name}.system;
26-
modules = configuredHosts.${name}.modules ++ (
27-
if configuredHosts.${name}.system == "aarch64-linux" then [ (nixpkgs + "/nixos/modules/installer/sd-card/sd-image-aarch64-installer.nix") ]
28-
else [ ]
29-
) ++ [
30-
({ ... }: {
31-
nixpkgs.system = system;
32-
nixpkgs.localSystem.system = system;
33-
nixpkgs.crossSystem = if system == configuredHosts.${name}.system then null else {
34-
system = configuredHosts.${name}.system;
35-
};
36-
})
37-
];
38-
specialArgs = {
39-
fleet = fleetLib.hostsToAttrs (host: configuredSystems.${host}.config);
18+
failedAssertions = map (x: x.message) (nixpkgs.lib.filter (x: !x.assertion) root.config.assertions);
19+
rootAssertWarn =
20+
if failedAssertions != [ ]
21+
then throw "Failed assertions:\n${nixpkgs.lib.concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}"
22+
else nixpkgs.lib.showWarnings root.config.warnings root;
23+
in
24+
rec {
25+
configuredHosts = rootAssertWarn.config.hosts;
26+
configuredSecrets = rootAssertWarn.config.secrets;
27+
configuredSystems = nixpkgs.lib.listToAttrs (
28+
map
29+
(
30+
name: {
31+
inherit name;
32+
value = nixpkgs.lib.nixosSystem {
33+
system = configuredHosts.${name}.system;
34+
modules = configuredHosts.${name}.modules ++ (
35+
if configuredHosts.${name}.system == "aarch64-linux" then [ (nixpkgs + "/nixos/modules/installer/sd-card/sd-image-aarch64-installer.nix") ]
36+
else [ ]
37+
) ++ [
38+
({ ... }: {
39+
nixpkgs.system = system;
40+
nixpkgs.localSystem.system = system;
41+
nixpkgs.crossSystem = if system == configuredHosts.${name}.system then null else {
42+
system = configuredHosts.${name}.system;
43+
};
44+
})
45+
];
46+
specialArgs = {
47+
inherit fleetLib;
48+
fleet = fleetLib.hostsToAttrs (host: configuredSystems.${host}.config);
49+
};
4050
};
41-
};
42-
}
43-
)
44-
(builtins.attrNames root.config.hosts)
45-
); #nixpkgs.lib.nixosSystem {}
46-
});
51+
}
52+
)
53+
(builtins.attrNames rootAssertWarn.config.hosts)
54+
); #nixpkgs.lib.nixosSystem {}
55+
});
4756
}

lib/fleetLib.nix

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Shared functions for fleet configuration, available as `fleet` module argument
2-
{ nixpkgs, hosts }: with nixpkgs.lib; rec {
3-
# Modules can't register hosts because of infinite recursion
4-
hostNames = attrNames hosts;
2+
{ nixpkgs, hostNames }: with nixpkgs.lib; rec {
53
hostsToAttrs = f: listToAttrs (
64
map (name: { inherit name; value = f name; }) hostNames
75
);
@@ -25,4 +23,7 @@
2523
a = elemAt sorted 0;
2624
b = elemAt sorted 1;
2725
};
26+
hostPairName = this: other:
27+
if this < other then "${this}-${other}"
28+
else "${other}-${this}";
2829
}

modules/fleet/_modules.nix

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[
2+
./assertions.nix
23
./meta.nix
34
./secrets.nix
45
]

modules/fleet/assertions.nix

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{ lib, ... }:
2+
3+
with lib;
4+
5+
{
6+
7+
options = {
8+
9+
assertions = mkOption {
10+
type = types.listOf types.unspecified;
11+
internal = true;
12+
default = [ ];
13+
example = [{ assertion = false; message = "you can't enable this for that reason"; }];
14+
description = ''
15+
This option allows modules to express conditions that must
16+
hold for the evaluation of the system configuration to
17+
succeed, along with associated error messages for the user.
18+
'';
19+
};
20+
21+
warnings = mkOption {
22+
internal = true;
23+
default = [ ];
24+
type = types.listOf types.str;
25+
example = [ "The `foo' service is deprecated and will go away soon!" ];
26+
description = ''
27+
This option allows modules to show warnings to users during
28+
the evaluation of the system configuration.
29+
'';
30+
};
31+
32+
};
33+
# impl of assertions is in <fleet/lib/default.nix>
34+
}

modules/fleet/meta.nix

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{ lib, fleet, config, ... }: with lib;
1+
{ lib, fleetLib, config, ... }: with lib;
22
let
33
host = with types; {
44
options = {
@@ -42,7 +42,7 @@ in
4242
};
4343
};
4444
config = {
45-
hosts = fleet.hostsToAttrs (host: {
45+
hosts = fleetLib.hostsToAttrs (host: {
4646
modules = config.globalModules;
4747
});
4848
globalModules = import ../../nixos/modules/module-list.nix;

modules/fleet/secrets.nix

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
1-
{ lib, fleet, config, ... }: with lib;
1+
{ lib, fleetLib, config, ... }: with lib; with fleetLib;
22
let
33
sharedSecret = with types; {
44
options = {
55
owners = mkOption {
6+
type = listOf str;
7+
description = ''
8+
For which owners this secret is currently encrypted,
9+
if not matches expectedOwners - then this secret is considered outdated, and
10+
should be regenerated/reencrypted
11+
'';
12+
};
13+
expectedOwners = mkOption {
614
type = listOf str;
715
description = ''
816
List of hosts to encrypt secret for
917
1018
Secrets would be decrypted and stored to /run/secrets/$\{name} on owners
1119
'';
20+
default = [ ];
1221
};
1322
generator = mkOption {
1423
type = package;
@@ -67,7 +76,13 @@ in
6776
description = "Host secrets";
6877
};
6978
};
70-
config = with fleet; {
79+
config = {
80+
assertions = mapAttrsToList
81+
(name: secret: {
82+
assertion = builtins.sort (a: b: a < b) secret.owners == builtins.sort (a: b: a < b) secret.expectedOwners;
83+
message = "Shared secret ${name} is expected to be encrypted for ${builtins.toJSON secret.expectedOwners}, but it is encrypted for ${builtins.toJSON secret.owners}";
84+
})
85+
config.sharedSecrets;
7186
hosts = hostsToAttrs (host: {
7287
modules =
7388
let

0 commit comments

Comments
 (0)