nixos/kanidm: merge recursively with extraJsonFile (#411439)

Changed files
+46 -4
nixos
modules
services
security
tests
+4 -4
nixos/modules/services/security/kanidm.nix
···
finalJson =
if cfg.provision.extraJsonFile != null then
-
"<(${lib.getExe pkgs.jq} -s '.[0] * .[1]' ${provisionStateJson} ${cfg.provision.extraJsonFile})"
+
''
+
<(${lib.getExe pkgs.yq-go} '. *+ load("${cfg.provision.extraJsonFile}") | (.. | select(type == "!!seq")) |= unique' ${provisionStateJson})
+
''
else
provisionStateJson;
···
description = ''
A JSON file for provisioning persons, groups & systems.
Options set in this file take precedence over values set using the other options.
-
In the case of duplicates, `jq` will remove all but the last one
-
when merging this file with the options.
+
The files get deeply merged, and deduplicated.
The accepted JSON schema can be found at <https://github.com/oddlama/kanidm-provision#json-schema>.
-
Note: theoretically `jq` cannot merge nested types, but this does not pose an issue as kanidm-provision's JSON scheme does not use nested types.
'';
type = types.nullOr types.path;
default = null;
+42
nixos/tests/kanidm-provisioning.nix
···
};
};
+
specialisation.extraJsonFile.configuration =
+
{ ... }:
+
{
+
services.kanidm.provision = lib.mkForce {
+
enable = true;
+
idmAdminPasswordFile = pkgs.writeText "idm-admin-pw" provisionIdmAdminPassword;
+
+
extraJsonFile = pkgs.writeText "extra-json.json" (
+
builtins.toJSON {
+
persons.testuser2.displayName = "Test User 2";
+
groups.testgroup1.members = [ "testuser2" ];
+
}
+
);
+
+
groups.testgroup1 = { };
+
+
persons.testuser1 = {
+
displayName = "Test User 1";
+
groups = [ "testgroup1" ];
+
};
+
};
+
};
+
security.pki.certificateFiles = [ certs.ca.cert ];
networking.hosts."::1" = [ serverDomain ];
···
out = provision.succeed("kanidm system oauth2 get service2")
assert_lacks(out, "name: service2")
+
+
provision.succeed("kanidm logout -D idm_admin")
+
+
with subtest("Test Provisioning - extraJsonFile"):
+
provision.succeed('${specialisations}/extraJsonFile/bin/switch-to-configuration test')
+
provision_login("${provisionIdmAdminPassword}")
+
+
out = provision.succeed("kanidm group get testgroup1")
+
assert_contains(out, "name: testgroup1")
+
+
out = provision.succeed("kanidm person get testuser1")
+
assert_contains(out, "name: testuser1")
+
+
out = provision.succeed("kanidm person get testuser2")
+
assert_contains(out, "name: testuser2")
+
+
out = provision.succeed("kanidm group get testgroup1")
+
assert_contains(out, "member: testuser1")
+
assert_contains(out, "member: testuser2")
provision.succeed("kanidm logout -D idm_admin")
'';