{ config, lib, pkgs, sources, ... }: let inherit (lib) mapAttrs' mkEnableOption mkIf mkOption nameValuePair types; package = import sources.linkal { inherit pkgs; }; cfg = config.dgn-linkal; jsonFormat = pkgs.formats.json { }; in { options.dgn-linkal = { enable = mkEnableOption "the linkal server."; package = mkOption { type = types.package; default = package.overrideAttrs (_: { buildInputs = [ ]; }); }; domain = mkOption { type = types.str; }; calendarGroups = mkOption { type = let inherit (types) attrsOf port submodule; in attrsOf (submodule { options = { port = mkOption { type = port; }; calendars = mkOption { inherit (jsonFormat) type; }; }; }); default = { }; }; }; config = mkIf cfg.enable { systemd.services = mapAttrs' (name: { port, calendars }: nameValuePair "linkal-${name}" { description = "Linkal - ${name}"; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "simple"; ExecStart = "${cfg.package}/bin/linkal --port ${ builtins.toString port } --calendar-file ${ jsonFormat.generate "linkal-${name}.json" { inherit calendars; } }"; }; }) cfg.calendarGroups; # Configure bind for DNS certificate validation on *.cal.dgnum.eu. # services.bind = { # enable = true; # ipv4Only = true; # extraConfig = '' # include "${config.age.secrets."named-bind_dnskeys_conf".path}"; # ''; # # zones = [rec { # name = "cal.dgnum.eu"; # file = "/var/db/bind/${name}"; # master = true; # extraConfig = '' # allow-update { key "rfc2136key.cal.dgnum.eu"; }; # ''; # }]; # }; # # networking.firewall = { # allowedTCPPorts = [ 53 ]; # allowedUDPPorts = [ 53 ]; # }; # # dgn-secrets.options = [{ named-bind_dnskeys_conf.owner = "named"; }]; # # # Configure ACME for DNS certificate validation # security.acme = { # acceptTerms = true; # defaults = { # dnsProvider = "rfc2136"; # credentialsFile = config.age.secrets."acme-certs_secret".path; # dnsPropagationCheck = false; # }; # }; services.nginx = { enable = true; virtualHosts = mapAttrs' (name: { port, ... }: nameValuePair "${name}.${cfg.domain}" { enableACME = true; # acmeRoot = null; # Use DNS-01 validation forceSSL = true; locations."/".proxyPass = "http://127.0.0.1:${builtins.toString port}/"; }) cfg.calendarGroups; }; }; }