selfhostblocks/test/blocks/lib.nix
2025-10-28 22:17:00 +01:00

151 lines
5.1 KiB
Nix

{ pkgs, lib, ... }:
let
pkgs' = pkgs;
in
{
template =
let
aSecret = pkgs.writeText "a-secret.txt" "Secret of A";
bSecret = pkgs.writeText "b-secret.txt" "Secret of B";
userConfig = {
a.a.source = aSecret;
b.source = bSecret;
b.transform = v: "prefix-${v}-suffix";
c = "not secret C";
d.d = "not secret D";
};
wantedConfig = {
a.a = "Secret of A";
b = "prefix-Secret of B-suffix";
c = "not secret C";
d.d = "not secret D";
};
configWithTemplates = lib.shb.withReplacements userConfig;
nonSecretConfigFile = pkgs.writeText "config.yaml.template" (
lib.generators.toJSON { } configWithTemplates
);
replacements = lib.shb.getReplacements userConfig;
replaceInTemplate = lib.shb.replaceSecretsScript {
file = nonSecretConfigFile;
resultPath = "/var/lib/config.yaml";
inherit replacements;
};
replaceInTemplateJSON = lib.shb.replaceSecrets {
inherit userConfig;
resultPath = "/var/lib/config.json";
generator = lib.shb.replaceSecretsFormatAdapter (pkgs.formats.json { });
};
replaceInTemplateJSONGen = lib.shb.replaceSecrets {
inherit userConfig;
resultPath = "/var/lib/config_gen.json";
generator = lib.shb.replaceSecretsGeneratorAdapter (lib.generators.toJSON { });
};
replaceInTemplateXML = lib.shb.replaceSecrets {
inherit userConfig;
resultPath = "/var/lib/config.xml";
generator = lib.shb.replaceSecretsFormatAdapter (lib.shb.formatXML { enclosingRoot = "Root"; });
};
in
lib.shb.runNixOSTest {
name = "lib-template";
nodes.machine =
{ config, pkgs, ... }:
{
imports = [
(pkgs'.path + "/nixos/modules/profiles/headless.nix")
(pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix")
{
options = {
libtest.config = lib.mkOption {
type = lib.types.attrsOf (
lib.types.oneOf [
lib.types.str
lib.secretFileType
]
);
};
};
}
];
system.activationScripts = {
libtest = replaceInTemplate;
libtestJSON = replaceInTemplateJSON;
libtestJSONGen = replaceInTemplateJSONGen;
libtestXML = replaceInTemplateXML;
};
};
testScript =
{ nodes, ... }:
''
import json
from collections import ChainMap
from xml.etree import ElementTree
start_all()
machine.wait_for_file("/var/lib/config.yaml")
machine.wait_for_file("/var/lib/config.json")
machine.wait_for_file("/var/lib/config_gen.json")
machine.wait_for_file("/var/lib/config.xml")
def xml_to_dict_recursive(root):
all_descendants = list(root)
if len(all_descendants) == 0:
return {root.tag: root.text}
else:
merged_dict = ChainMap(*map(xml_to_dict_recursive, all_descendants))
return {root.tag: dict(merged_dict)}
wantedConfig = json.loads('${lib.generators.toJSON { } wantedConfig}')
with subtest("config"):
print(machine.succeed("cat ${pkgs.writeText "replaceInTemplate" replaceInTemplate}"))
gotConfig = machine.succeed("cat /var/lib/config.yaml")
print(gotConfig)
gotConfig = json.loads(gotConfig)
if wantedConfig != gotConfig:
raise Exception("\nwantedConfig: {}\n!= gotConfig: {}".format(wantedConfig, gotConfig))
with subtest("config JSON Gen"):
print(machine.succeed("cat ${pkgs.writeText "replaceInTemplateJSONGen" replaceInTemplateJSONGen}"))
gotConfig = machine.succeed("cat /var/lib/config_gen.json")
print(gotConfig)
gotConfig = json.loads(gotConfig)
if wantedConfig != gotConfig:
raise Exception("\nwantedConfig: {}\n!= gotConfig: {}".format(wantedConfig, gotConfig))
with subtest("config JSON"):
print(machine.succeed("cat ${pkgs.writeText "replaceInTemplateJSON" replaceInTemplateJSON}"))
gotConfig = machine.succeed("cat /var/lib/config.json")
print(gotConfig)
gotConfig = json.loads(gotConfig)
if wantedConfig != gotConfig:
raise Exception("\nwantedConfig: {}\n!= gotConfig: {}".format(wantedConfig, gotConfig))
with subtest("config XML"):
print(machine.succeed("cat ${pkgs.writeText "replaceInTemplateXML" replaceInTemplateXML}"))
gotConfig = machine.succeed("cat /var/lib/config.xml")
print(gotConfig)
gotConfig = xml_to_dict_recursive(ElementTree.XML(gotConfig))['Root']
if wantedConfig != gotConfig:
raise Exception("\nwantedConfig: {}\n!= gotConfig: {}".format(wantedConfig, gotConfig))
'';
};
}