nixos/tailscale: add authKeyParameters

Adds `config.services.tailscale.authKeyParameters`
This commit is contained in:
Lucas Chaim 2024-08-30 20:48:17 -03:00
parent dec1098ad0
commit 9e6338ffaf
2 changed files with 40 additions and 1 deletions

View File

@ -516,6 +516,9 @@
- `lib.misc.mapAttrsFlatten` is now formally deprecated and will be removed in future releases; use the identical [`lib.attrsets.mapAttrsToList`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.attrsets.mapAttrsToList) instead.
- Tailscale's `authKeyFile` can now have its corresponding parameters set through `config.services.tailscale.authKeyParameters`, allowing for non-ephemeral unsupervised deployment and more.
See [Registering new nodes using OAuth credentials](https://tailscale.com/kb/1215/oauth-clients#registering-new-nodes-using-oauth-credentials) for the supported options.
- `nixosTests` now provide a working IPv6 setup for VLAN 1 by default.
- Kanidm can now be provisioned using the new [`services.kanidm.provision`] option, but requires using a patched version available via `pkgs.kanidm.withSecretProvisioning`.

View File

@ -60,6 +60,33 @@ in {
'';
};
authKeyParameters = mkOption {
type = types.submodule {
options = {
ephemeral = mkOption {
type = types.nullOr types.bool;
default = null;
description = "Whether to register as an ephemeral node.";
};
preauthorized = mkOption {
type = types.nullOr types.bool;
default = null;
description = "Whether to skip manual device approval.";
};
baseURL = mkOption {
type = types.nullOr types.str;
default = null;
description = "Base URL for the Tailscale API.";
};
};
};
default = { };
description = ''
Extra parameters to pass after the auth key.
See https://tailscale.com/kb/1215/oauth-clients#registering-new-nodes-using-oauth-credentials
'';
};
extraUpFlags = mkOption {
description = ''
Extra flags to pass to {command}`tailscale up`. Only applied if `authKeyFile` is specified.";
@ -124,13 +151,22 @@ in {
# https://github.com/tailscale/tailscale/blob/v1.72.1/ipn/backend.go#L24-L32
script = let
statusCommand = "${lib.getExe cfg.package} status --json --peers=false | ${lib.getExe pkgs.jq} -r '.BackendState'";
paramToString = v:
if (builtins.isBool v) then (lib.boolToString v)
else (toString v);
params = lib.pipe cfg.authKeyParameters [
(lib.filterAttrs (_: v: v != null))
(lib.mapAttrsToList (k: v: "${k}=${paramToString v}"))
(builtins.concatStringsSep "&")
(params: if params != "" then "?${params}" else "")
];
in ''
while [[ "$(${statusCommand})" == "NoState" ]]; do
sleep 0.5
done
status=$(${statusCommand})
if [[ "$status" == "NeedsLogin" || "$status" == "NeedsMachineAuth" ]]; then
${lib.getExe cfg.package} up --auth-key 'file:${cfg.authKeyFile}' ${escapeShellArgs cfg.extraUpFlags}
${lib.getExe cfg.package} up --auth-key "$(cat ${cfg.authKeyFile})${params}" ${escapeShellArgs cfg.extraUpFlags}
fi
'';
};