nix-home/modules/cloud/traefik/config.nix

90 lines
2.5 KiB
Nix

{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.cloud.traefik;
# Copied from traefik.nix
jsonValue = with types;
let
valueType = nullOr (oneOf [
bool
int
float
str
(lazyAttrsOf valueType)
(listOf valueType)
]) // {
description = "JSON value";
emptyValue.value = { };
};
in valueType;
hostType = with types; submodule {
options = {
host = mkOption {
type = str;
description = "The host for the router filter";
};
path = mkOption {
type = nullOr str;
default = null;
description = "The path for the router filter (exact path is matched)";
};
filter = mkOption {
type = nullOr str;
default = null;
description = "The filter syntax for the router. Overrides `host` and `path` if provided";
};
port = mkOption {
type = types.port;
description = "The port that the service is listening on";
};
entrypoints = mkOption {
type = listOf (enum ["http" "https" "smtp-submission" "imap"]);
default = [ "https" ];
description = "The entrypoints that will serve the host";
};
middlewares = mkOption {
type = listOf jsonType;
default = [];
description = "The middlewares to be used with the host.";
};
};
};
# Returns the filter given a host configuration
filterOfHost = host :
if host.filter != null then host.filter
else if host.path == null then "Host(`${host.host}`)"
else "Host(`${host.host}`) && Path(`${host.path}`)";
# Turns a host configuration into dynamic traefik configuration
hostToConfig = name : host : {
http.routers."${name}-router" = {
rule = filterOfHost host;
entryPoints = host.entrypoints;
tls.certResolver = "le";
service = "${name}-service";
middlewares = lists.imap0 (id: m: "${name}-middleware-${toString id}") host.middlewares;
};
http.services."${name}-service".loadBalancer.servers = [
{ url = "http://localhost:${toString host.port}"; }
];
http.middlewares = builtins.listToAttrs (lists.imap0 (id: v: {
name = "${name}-middleware-${toString id}";
value = v;
}) host.middlewares);
};
in
{
options.cloud.traefik.hosts = mkOption {
type = types.attrsOf hostType;
default = {};
description = "The HTTP hosts to run on the server";
};
config.cloud.traefik.config = builtins.foldl' attrsets.recursiveUpdate {} (attrsets.mapAttrsToList hostToConfig cfg.hosts);
}