Compare commits
No commits in common. "28169a8bd76c0a895787c7d194e1a5e4ef6276a2" and "6f32855cb7ecad975e0f5bbe0a9d340384696703" have entirely different histories.
28169a8bd7
...
6f32855cb7
7 changed files with 11 additions and 111 deletions
|
@ -28,35 +28,6 @@ in
|
||||||
bootstrap_expect = builtins.length cfg.nodes.agent;
|
bootstrap_expect = builtins.length cfg.nodes.agent;
|
||||||
addresses.http = config.links.consulAgent.ipv4;
|
addresses.http = config.links.consulAgent.ipv4;
|
||||||
ports.http = config.links.consulAgent.port;
|
ports.http = config.links.consulAgent.port;
|
||||||
acl = {
|
|
||||||
enabled = true;
|
|
||||||
default_policy = "deny";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services = {
|
|
||||||
consul.serviceConfig.Type = "notify";
|
|
||||||
consul-load-smt = {
|
|
||||||
wantedBy = [ "consul.service" ];
|
|
||||||
after = [ "consul.service" ];
|
|
||||||
environment.CONSUL_HTTP_ADDR = config.links.consulAgent.tuple;
|
|
||||||
path = [
|
|
||||||
config.services.consul.package
|
|
||||||
];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
RemainAfterExit = true;
|
|
||||||
};
|
|
||||||
script = ''
|
|
||||||
while ! test -e /run/locksmith/consul-systemManagementToken; do
|
|
||||||
echo Waiting for System Management Token
|
|
||||||
systemctl start locksmith.service
|
|
||||||
sleep 5
|
|
||||||
done
|
|
||||||
export CONSUL_HTTP_TOKEN_FILE=/run/locksmith/consul-systemManagementToken
|
|
||||||
consul acl set-agent-token default "$(< /run/locksmith/consul-systemManagementToken)" # TODO: don't leak token on cmdline
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
{ cluster, config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
sentinelFile = "/var/lib/consul/nixos-acl-bootstrapped";
|
|
||||||
bootstrapTokenFile = "/run/keys/consul-bootstrap-token";
|
|
||||||
bootstrapConfig = "consul-bootstrap-config.json";
|
|
||||||
writeRules = rules: pkgs.writeText "consul-policy.json" (builtins.toJSON rules);
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
|
||||||
systemd.services = {
|
|
||||||
consul-acl-bootstrap = {
|
|
||||||
requires = [ "consul.service" ];
|
|
||||||
after = [ "consul.service" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
|
|
||||||
unitConfig.ConditionPathExists = "!${sentinelFile}";
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
PrivateTmp = true;
|
|
||||||
};
|
|
||||||
environment.CONSUL_HTTP_ADDR = config.links.consulAgent.tuple;
|
|
||||||
path = [
|
|
||||||
config.services.consul.package
|
|
||||||
pkgs.jq
|
|
||||||
];
|
|
||||||
script = ''
|
|
||||||
umask 77
|
|
||||||
if consul acl bootstrap --format=json > ${bootstrapConfig}; then
|
|
||||||
echo Bootstrapping:
|
|
||||||
jq -r .SecretID < ${bootstrapConfig} > ${bootstrapTokenFile}
|
|
||||||
export CONSUL_HTTP_TOKEN_FILE=${bootstrapTokenFile}
|
|
||||||
consul acl policy create --name operator-read --description "Read-only operator actions" --rules @${writeRules { operator = "read"; }}
|
|
||||||
consul acl policy create --name smt-read --description "Allow reading the encrypted system management token" --rules @${writeRules { key_prefix."secrets/locksmith/consul-systemManagementToken/".policy = "read"; }}
|
|
||||||
consul acl token update --id 00000000-0000-0000-0000-000000000002 --append-policy-name operator-read --append-policy-name smt-read
|
|
||||||
else
|
|
||||||
echo Bootstrap is already in progress elsewhere.
|
|
||||||
touch ${sentinelFile}
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
locksmith-provider-consul = {
|
|
||||||
unitConfig.ConditionPathExists = bootstrapTokenFile;
|
|
||||||
distributed.enable = lib.mkForce false;
|
|
||||||
environment = {
|
|
||||||
CONSUL_HTTP_ADDR = config.links.consulAgent.tuple;
|
|
||||||
CONSUL_HTTP_TOKEN_FILE = bootstrapTokenFile;
|
|
||||||
};
|
|
||||||
postStop = ''
|
|
||||||
rm -f ${bootstrapTokenFile}
|
|
||||||
touch ${sentinelFile}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.locksmith.providers.consul = {
|
|
||||||
wantedBy = [ "consul-acl-bootstrap.service" ];
|
|
||||||
after = [ "consul-acl-bootstrap.service" ];
|
|
||||||
secrets.systemManagementToken = {
|
|
||||||
nodes = cluster.config.services.consul.nodes.agent;
|
|
||||||
checkUpdate = "test -e ${bootstrapTokenFile}";
|
|
||||||
command = "cat ${bootstrapTokenFile}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -14,7 +14,6 @@ in
|
||||||
nodes = {
|
nodes = {
|
||||||
agent = [ "checkmate" "grail" "thunderskin" "VEGAS" "prophet" ];
|
agent = [ "checkmate" "grail" "thunderskin" "VEGAS" "prophet" ];
|
||||||
ready = config.services.consul.nodes.agent;
|
ready = config.services.consul.nodes.agent;
|
||||||
bootstrap = [ "grail" "VEGAS" ];
|
|
||||||
};
|
};
|
||||||
nixos = {
|
nixos = {
|
||||||
agent = [
|
agent = [
|
||||||
|
@ -22,11 +21,10 @@ in
|
||||||
./remote-api.nix
|
./remote-api.nix
|
||||||
];
|
];
|
||||||
ready = ./ready.nix;
|
ready = ./ready.nix;
|
||||||
bootstrap = ./bootstrap.nix;
|
|
||||||
};
|
};
|
||||||
simulacrum = {
|
simulacrum = {
|
||||||
enable = true;
|
enable = true;
|
||||||
deps = [ "wireguard" "locksmith" ];
|
deps = [ "wireguard" ];
|
||||||
settings = ./test.nix;
|
settings = ./test.nix;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -51,9 +51,4 @@ in
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.targets.consul-ready = {
|
|
||||||
description = "Consul is Ready";
|
|
||||||
requires = [ "consul-ready.service" ] ++ lib.optional config.services.consul.enable "consul-load-smt.service";
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
defaults.options.services.locksmith = lib.mkSinkUndeclaredOptions { };
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
@ -7,12 +11,12 @@
|
||||||
with subtest("should form cluster"):
|
with subtest("should form cluster"):
|
||||||
nodes = [ n for n in machines if n != nowhere ]
|
nodes = [ n for n in machines if n != nowhere ]
|
||||||
for machine in nodes:
|
for machine in nodes:
|
||||||
machine.succeed("systemctl start consul-ready.target")
|
machine.succeed("systemctl start consul-ready.service")
|
||||||
for machine in nodes:
|
for machine in nodes:
|
||||||
consulConfig = json.loads(machine.succeed("cat /etc/consul.json"))
|
consulConfig = json.loads(machine.succeed("cat /etc/consul.json"))
|
||||||
addr = consulConfig["addresses"]["http"]
|
addr = consulConfig["addresses"]["http"]
|
||||||
port = consulConfig["ports"]["http"]
|
port = consulConfig["ports"]["http"]
|
||||||
setEnv = f"CONSUL_HTTP_ADDR={addr}:{port} CONSUL_HTTP_TOKEN_FILE=/run/locksmith/consul-systemManagementToken"
|
setEnv = f"CONSUL_HTTP_ADDR={addr}:{port}"
|
||||||
memberList = machine.succeed(f"{setEnv} consul members --status=alive")
|
memberList = machine.succeed(f"{setEnv} consul members --status=alive")
|
||||||
for machine2 in nodes:
|
for machine2 in nodes:
|
||||||
assert machine2.name in memberList
|
assert machine2.name in memberList
|
||||||
|
|
|
@ -43,15 +43,14 @@ in
|
||||||
hasSpecialPrefix = elem (substring 0 1 ExecStart) [ "@" "-" ":" "+" "!" ];
|
hasSpecialPrefix = elem (substring 0 1 ExecStart) [ "@" "-" ":" "+" "!" ];
|
||||||
in assert !hasSpecialPrefix; pkgs.writeTextDir "etc/systemd/system/${n}.service.d/distributed.conf" ''
|
in assert !hasSpecialPrefix; pkgs.writeTextDir "etc/systemd/system/${n}.service.d/distributed.conf" ''
|
||||||
[Unit]
|
[Unit]
|
||||||
Requires=consul-ready.target
|
Requires=consul-ready.service
|
||||||
After=consul-ready.target
|
After=consul-ready.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStartPre=${waitForConsul} 'services/${n}%i'
|
ExecStartPre=${waitForConsul} 'services/${n}%i'
|
||||||
ExecStart=
|
ExecStart=
|
||||||
ExecStart=${consul}/bin/consul lock --name=${n} --n=${toString cfg.replicas} --shell=false --child-exit-code 'services/${n}%i' ${optionalString (cfg.registerService != null) runWithRegistration} ${ExecStart}
|
ExecStart=${consul}/bin/consul lock --name=${n} --n=${toString cfg.replicas} --shell=false --child-exit-code 'services/${n}%i' ${optionalString (cfg.registerService != null) runWithRegistration} ${ExecStart}
|
||||||
Environment="CONSUL_HTTP_ADDR=${consulHttpAddr}"
|
Environment="CONSUL_HTTP_ADDR=${consulHttpAddr}"
|
||||||
Environment="CONSUL_HTTP_TOKEN_FILE=/run/locksmith/consul-systemManagementToken"
|
|
||||||
${optionalString (v.serviceConfig ? RestrictAddressFamilies) "RestrictAddressFamilies=AF_NETLINK"}
|
${optionalString (v.serviceConfig ? RestrictAddressFamilies) "RestrictAddressFamilies=AF_NETLINK"}
|
||||||
${optionalString (cfg.registerService != null) "ExecStopPost=${svc.commands.deregister}"}
|
${optionalString (cfg.registerService != null) "ExecStopPost=${svc.commands.deregister}"}
|
||||||
''))
|
''))
|
||||||
|
|
|
@ -12,7 +12,6 @@ let
|
||||||
|
|
||||||
consulRegisterScript = pkgs.writeShellScript "consul-register" ''
|
consulRegisterScript = pkgs.writeShellScript "consul-register" ''
|
||||||
export CONSUL_HTTP_ADDR='${consulHttpAddr}'
|
export CONSUL_HTTP_ADDR='${consulHttpAddr}'
|
||||||
export CONSUL_HTTP_TOKEN_FILE=/run/locksmith/consul-systemManagementToken
|
|
||||||
while ! ${consul} services register "$1"; do
|
while ! ${consul} services register "$1"; do
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
@ -20,7 +19,6 @@ let
|
||||||
|
|
||||||
consulDeregisterScript = pkgs.writeShellScript "consul-deregister" ''
|
consulDeregisterScript = pkgs.writeShellScript "consul-deregister" ''
|
||||||
export CONSUL_HTTP_ADDR='${consulHttpAddr}'
|
export CONSUL_HTTP_ADDR='${consulHttpAddr}'
|
||||||
export CONSUL_HTTP_TOKEN_FILE=/run/locksmith/consul-systemManagementToken
|
|
||||||
for i in {1..5}; do
|
for i in {1..5}; do
|
||||||
if ${consul} services deregister "$1"; then
|
if ${consul} services deregister "$1"; then
|
||||||
break
|
break
|
||||||
|
@ -83,8 +81,8 @@ let
|
||||||
}.${mode};
|
}.${mode};
|
||||||
value = {
|
value = {
|
||||||
direct = {
|
direct = {
|
||||||
after = [ "consul-ready.target" ];
|
after = [ "consul-ready.service" ];
|
||||||
requires = [ "consul-ready.target" ];
|
requires = [ "consul-ready.service" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStartPost = register servicesJson;
|
ExecStartPost = register servicesJson;
|
||||||
ExecStopPost = deregister servicesJson;
|
ExecStopPost = deregister servicesJson;
|
||||||
|
|
Loading…
Add table
Reference in a new issue