{ config, lib, pkgs, ... }: with lib; let cfg = config.services.sa-core; instanceOpts = { name, ... }: { options = { domain = mkOption { type = types.nullOr types.str; default = null; description = lib.mdDoc '' Domain of the website to scan. Defaults to attribute name in instances. ''; example = "example.org"; }; email = mkOption { type = types.str; default = "office@scana11y.com"; description = lib.mdDoc '' Email where to send scan reports. ''; example = "example.org"; }; maxPages = mkOption { type = types.int; default = 100; description = lib.mdDoc '' Maximum number of pages to scan. ''; example = "100"; }; timerConfig = mkOption { type = types.attrs; default = { OnCalendar = "monthly"; Persistent = true; RandomizedDelaySec = "1h"; # spread load a bit }; description = lib.mdDoc '' Configuration for the systemd timer. ''; }; }; }; in { options.services.sa-core = { instances = mkOption { type = types.attrsOf (types.submodule instanceOpts); default = {}; description = lib.mdDoc "Define ScanA11y instances here."; example = literalExpression '' { "example.org" = { domain = "example.org"; email = "test@example.org"; }; } ''; }; }; config = { virtualisation = { docker.enable = true; }; systemd.timers = mapAttrs' (instance: instanceOpts: let domain = if instanceOpts.domain != null then instanceOpts.domain else instance; in nameValuePair ("sa-core-" + domain) { wantedBy = [ "timers.target" ]; timerConfig = instanceOpts.timerConfig; } ) cfg.instances; systemd.services = mapAttrs' (instance: instanceOpts: let domain = if instanceOpts.domain != null then instanceOpts.domain else instance; maxPages = if instanceOpts.maxPages != null then toString instanceOpts.maxPages else "100"; in nameValuePair ("sa-core-" + domain) { description = "ScanA11y ${domain}"; wants = [ "docker.service" ]; after = [ "docker.service" "network-online.target" ]; serviceConfig = { Type = "oneshot"; User = "scana11y_com"; Group= "nginx"; SupplementaryGroups = "docker"; }; path = [ pkgs.docker pkgs.wkhtmltopdf ]; script = '' exec ${pkgs.sa-core}/bin/sa-core scan \ -domain=${domain} \ -depth=3 \ -max-pages=${maxPages} \ -image=cloonar/sa-core:v0.1.3 \ -output=/var/www/scana11y.com/public/reports \ -wkhtmltopdf=${pkgs.wkhtmltopdf}/bin/wkhtmltopdf \ -email-server=imap.cloonar.com \ -email-username=office@scana11y.com \ -email-password-file=${config.sops.secrets.sa-core-mailpw.path} \ -email-sender=office@scana11y.com \ -email-recipient=${instanceOpts.email} \ -keep 6 \ -webroot=https://scana11y.com/reports ''; } ) cfg.instances; sops.secrets.sa-core-mailpw.owner = "scana11y_com"; }; }