Skip to content

Commit

Permalink
init vault integration test
Browse files Browse the repository at this point in the history
  • Loading branch information
srhb authored and cafkafk committed Sep 3, 2024
1 parent 347d065 commit 6a94e93
Show file tree
Hide file tree
Showing 2 changed files with 258 additions and 0 deletions.
7 changes: 7 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
pkgs = import nixpkgs {
inherit system;
overlays = [ crane-overlay self.overlays.default ];
config = {
allowUnfreePredicate = pkg:
builtins.elem (builtins.parseDrvName (pkg.name or pkg.pname)).name [
"vault"
];
};
};
crane-overlay = final: prev: {
# crane's lib is not exposed as an overlay in its flake (should be added
Expand All @@ -25,6 +31,7 @@
in {
packages.${system}.${pname} = pkgs.${pname};
defaultPackage.${system} = pkgs.${pname};
checks.${system}.vault = pkgs.callPackage ./nixos/vault-test.nix {};

overlays.default = final: prev: {
"${pname}" = final.craneLib.buildPackage {
Expand Down
251 changes: 251 additions & 0 deletions nixos/vault-test.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
{ lib, pkgs }:
let
nixos-lib = import (pkgs.path + "/nixos/lib") { };
acme-test-module = "${pkgs.path}/nixos/tests/common/acme/server";

role_id_path = "/tmp/vault-role-id";
secret_id_path = "/tmp/vault-secret-id";

domain = "faythe.test";
vault_host = "vault.${domain}";
ns_host = "ns.${domain}";

# dev server
vault_addr = "http://localhost:8200";

in
nixos-lib.runTest (
test@{ nodes, ... }:
{
hostPkgs = pkgs;
name = "faythe-vault-test";
defaults = {
nixpkgs.pkgs = pkgs;
networking.nameservers = lib.mkForce [ nodes.ns.networking.primaryIPAddress ];
networking.dhcpcd.enable = false;
security.pki.certificateFiles = [ nodes.acme.test-support.acme.caCert ];
networking.hosts."${nodes.acme.networking.primaryIPAddress}" = [ nodes.acme.test-support.acme.caDomain ];
};
nodes = {
acme =
{ pkgs, ... }:
{
imports = [ acme-test-module ];
};

ns =
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
dig
dnsutils
];

networking.firewall.allowedTCPPorts = [ 53 ];
networking.firewall.allowedUDPPorts = [ 53 ];

services.bind.enable = true;

services.bind.zones."${domain}" = {
master = true;
file = "/etc/bind/zones/${domain}.zone";
# the bind zone module is very opinionated and this sets allow-transfer.
slaves = [ nodes.client.networking.primaryIPAddress ];
extraConfig = ''
allow-update { ${nodes.client.networking.primaryIPAddress}; };
'';
};

# Hack to allow access to the directory copied from environment.etc
systemd.services.bind.serviceConfig.ExecStartPre = "+${pkgs.coreutils}/bin/chown named /etc/bind/zones";

environment.etc."bind/zones/${domain}.zone" = {
mode = "0644";
user = "named";
group = "named";
text = ''
$TTL 60
${domain}. IN SOA ${ns_host}. admin.${domain}. ( 1 3h 1h 1w 1d )
@ IN NS ${ns_host}.
${ns_host}. IN A ${nodes.ns.networking.primaryIPAddress}
${vault_host}. IN A ${nodes.client.networking.primaryIPAddress}
'';
};
};

client =
{ pkgs, config, ... }:
let

faytheConfig = {
vault_monitor_configs = [
{
inherit role_id_path secret_id_path vault_addr;
key_prefix = "path1";
specs = [
{
name = "path1-test";
cn = "path1.${domain}";
}
];
}
# Multiple vaultmonitorconfigs break faythe currently, commented out
# {
# inherit role_id_path secret_id_path vault_addr;
# key_prefix = "path2";
# specs = [
# {
# name = "path2-test";
# cn = "path2.${domain}";
# }
# ];
# }
];
lets_encrypt_url = "https://${nodes.acme.test-support.acme.caDomain}/dir";
lets_encrypt_email = "test_mail@${domain}";
zones = {
"${domain}" = {
server = ns_host;
key = "test";
};
};
val_dns_servers = [ ns_host ];
};

faytheConfigFile = pkgs.writeText "faythe.config.json" (builtins.toJSON faytheConfig);

faytheConfigFileChecked = pkgs.runCommand "faythe.config.checked.json" { } ''
${pkgs.faythe}/bin/faythe --config-check ${faytheConfigFile}
ln -s ${faytheConfigFile} $out
'';
in
{
environment.systemPackages = with pkgs; [
dig
dnsutils
vault
getent
];

environment.variables.VAULT_ADDR = vault_addr;

services.vault = {
enable = true;
# start unsealed and with known root token
dev = true;
devRootTokenID = "vaultroot";
};

# FIXME: upstream this, makes ordering nicer
systemd.services.vault.serviceConfig.Type = "notify";

systemd.services.vault-provision = {
path = with pkgs; [
vault
getent
];
environment.VAULT_ADDR = vault_addr;
wants = [ "vault.service" ];
after = [ "vault.service" ];
serviceConfig.Type = "oneshot";

script = ''
set -x
set -euo pipefail
vault login ${config.services.vault.devRootTokenID}
vault policy write faythe-policy ${
pkgs.writeText "faythe-policy.json" (
builtins.toJSON {
path."kv/data/path1/*" = {
capabilities = [
"list"
"read"
"create"
"update"
];
};
path."kv/metadata/path1/*" = {
capabilities = [
"list"
"read"
"create"
"update"
];
};
path."kv/data/path2/*" = {
capabilities = [
"list"
"read"
"create"
"update"
];
};
path."kv/metadata/path2/*" = {
capabilities = [
"list"
"read"
"create"
"update"
];
};
}
)
}
vault auth enable approle
vault write auth/approle/role/faythe type=service policies=faythe-policy
vault read -field=role_id auth/approle/role/faythe/role-id > ${role_id_path}
vault write -f -field=secret_id auth/approle/role/faythe/secret-id > ${secret_id_path}
vault secrets enable -path=kv kv-v2
'';
};

systemd.services.faythe = {
path = with pkgs; [
dnsutils
dig
];
wantedBy = [ "multi-user.target" ];
wants = [ "vault-provision.service" ];
after = [ "vault-provision.service" ];
serviceConfig = {
ExecStart = "${pkgs.faythe}/bin/faythe ${faytheConfigFileChecked}";
};
};
};
};
testScript = ''
start_all()
ns.wait_for_unit("network-online.target")
acme.wait_for_unit("network-online.target")
client.wait_for_unit("network-online.target")
ns.wait_for_unit("bind.service")
client.wait_until_succeeds("ping -c1 ${nodes.ns.networking.primaryIPAddress}")
client.wait_until_succeeds("host ${vault_host}")
client.fail("host doesnotexist.${domain}")
client.wait_for_unit("faythe.service")
with subtest("Can get certs"):
client.wait_until_succeeds("""
vault kv get kv/path1/path1-test/cert
# vault kv get kv/path2/path2-test/cert
""")
with subtest("No failed dispatch in vaultrs"):
client.fail("""
journalctl -u faythe | grep -q "dispatch task is gone: runtime dropped the dispatch task"
""")
'';
}
)

0 comments on commit 6a94e93

Please sign in to comment.