feat: add modularity to scana11y

This commit is contained in:
2025-10-02 19:45:08 +02:00
parent 8ab1c91b38
commit 305ce21e41
4 changed files with 129 additions and 45 deletions

View File

@@ -38,6 +38,7 @@
# comment out for first build, so ssh key and config is present
# otherwise the build will fail
./modules/sa-core.nix
./modules/scana11y.nix
];

View File

@@ -1,27 +1,109 @@
{ config, pkgs, ... }:
{ 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;
};
users.users.scana11y_com.extraGroups = [ "docker" ];
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."scana11y-wohnservice-wien.at" = {
description = "ScanA11y wohnservice-wien.at";
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=wohnservice-wien.at \
-domain=${domain} \
-depth=3 \
-max-pages=100 \
-max-pages=${maxPages} \
-image=cloonar/sa-core:v0.1.3 \
-output=/var/www/scana11y.com/public/reports \
-wkhtmltopdf=${pkgs.wkhtmltopdf}/bin/wkhtmltopdf \
@@ -29,20 +111,13 @@
-email-username=office@scana11y.com \
-email-password-file=${config.sops.secrets.sa-core-mailpw.path} \
-email-sender=office@scana11y.com \
-email-recipient=dominik.polakovics@cloonar.com \
-email-recipient=${instanceOpts.email} \
-keep 6 \
-webroot=https://scana11y.com/reports
'';
};
}
) cfg.instances;
systemd.timers."scana11y-wohnservice-wien.at" = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "monthly";
Persistent = true;
RandomizedDelaySec = "1h"; # spread load a bit
sops.secrets.sa-core-mailpw.owner = "scana11y_com";
};
};
sops.secrets.sa-core-mailpw.owner = "scana11y_com"; # written as root at activation
}

View File

@@ -0,0 +1,8 @@
{ config, pkgs, ... }:
{
services.sa-core.instances = {
"wohnservice-wien.at" = {
email = "dominik.polakovics@cloonar.com";
};
};
}

View File

@@ -2,13 +2,13 @@
let
saRepoSrc = builtins.fetchGit {
url = "ssh://gitea@git.cloonar.com/ScanA11y/sa-core.git";
rev = "844c5a6b95ae28ab17da127011d1f027680d1a9a";
rev = "0d33fdb79b62c270d230ad307341ae107be96600";
};
in
buildGoModule rec {
pname = "sa-core";
version = "0.2.0";
version = "0.3.2";
src = saRepoSrc;