diff options
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/modules/installer/tools/nixos-build-vms/build-vms.nix | 2 | ||||
-rw-r--r-- | nixos/modules/misc/ids.nix | 2 | ||||
-rw-r--r-- | nixos/modules/module-list.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/mail/rss2email.nix | 136 | ||||
-rw-r--r-- | nixos/modules/services/monitoring/prometheus/alertmanager.nix | 77 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
-rw-r--r-- | nixos/tests/common/webroot/news-rss.xml | 15 | ||||
-rw-r--r-- | nixos/tests/prometheus.nix | 22 | ||||
-rw-r--r-- | nixos/tests/rss2email.nix | 66 |
9 files changed, 295 insertions, 27 deletions
diff --git a/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix b/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix index 2625f7661b78..c1028a0ad7e9 100644 --- a/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix +++ b/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix @@ -7,7 +7,7 @@ let nodes = import networkExpr; in with import ../../../../lib/testing.nix { inherit system; - pkgs = import ../.. { inherit system config; }; + pkgs = import ../../../../.. { inherit system config; }; }; (makeTest { inherit nodes; testScript = ""; }).driver diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 082b2732cc58..8ac12079548d 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -336,6 +336,7 @@ solr = 309; alerta = 310; minetest = 311; + rss2email = 312; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -632,6 +633,7 @@ solr = 309; alerta = 310; minetest = 311; + rss2email = 312; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index ae5084ca2a2a..505cb0336db2 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -330,6 +330,7 @@ ./services/mail/postgrey.nix ./services/mail/spamassassin.nix ./services/mail/rspamd.nix + ./services/mail/rss2email.nix ./services/mail/rmilter.nix ./services/mail/nullmailer.nix ./services/misc/airsonic.nix diff --git a/nixos/modules/services/mail/rss2email.nix b/nixos/modules/services/mail/rss2email.nix new file mode 100644 index 000000000000..5f3b2877008f --- /dev/null +++ b/nixos/modules/services/mail/rss2email.nix @@ -0,0 +1,136 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.rss2email; +in { + + ###### interface + + options = { + + services.rss2email = { + + enable = mkOption { + type = types.bool; + default = false; + description = "Whether to enable rss2email."; + }; + + to = mkOption { + type = types.str; + description = "Mail address to which to send emails"; + }; + + interval = mkOption { + type = types.str; + default = "12h"; + description = "How often to check the feeds, in systemd interval format"; + }; + + config = mkOption { + type = with types; attrsOf (either str (either int bool)); + default = {}; + description = '' + The configuration to give rss2email. + + Default will use system-wide <literal>sendmail</literal> to send the + email. This is rss2email's default when running + <literal>r2e new</literal>. + + This set contains key-value associations that will be set in the + <literal>[DEFAULT]</literal> block along with the + <literal>to</literal> parameter. + + See + <literal>https://github.com/rss2email/rss2email/blob/master/r2e.1</literal> + for more information on which parameters are accepted. + ''; + }; + + feeds = mkOption { + description = "The feeds to watch."; + type = types.attrsOf (types.submodule { + options = { + url = mkOption { + type = types.str; + description = "The URL at which to fetch the feed."; + }; + + to = mkOption { + type = with types; nullOr str; + default = null; + description = '' + Email address to which to send feed items. + + If <literal>null</literal>, this will not be set in the + configuration file, and rss2email will make it default to + <literal>rss2email.to</literal>. + ''; + }; + }; + }); + }; + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + users.groups = { + rss2email.gid = config.ids.gids.rss2email; + }; + + users.users = { + rss2email = { + description = "rss2email user"; + uid = config.ids.uids.rss2email; + group = "rss2email"; + }; + }; + + services.rss2email.config.to = cfg.to; + + systemd.services.rss2email = let + conf = pkgs.writeText "rss2email.cfg" (lib.generators.toINI {} ({ + DEFAULT = cfg.config; + } // lib.mapAttrs' (name: feed: nameValuePair "feed.${name}" ( + { inherit (feed) url; } // + lib.optionalAttrs (feed.to != null) { inherit (feed) to; } + )) cfg.feeds + )); + in + { + preStart = '' + mkdir -p /var/rss2email + chmod 700 /var/rss2email + + cp ${conf} /var/rss2email/conf.cfg + if [ ! -f /var/rss2email/db.json ]; then + echo '{"version":2,"feeds":[]}' > /var/rss2email/db.json + fi + + chown -R rss2email:rss2email /var/rss2email + ''; + path = [ pkgs.system-sendmail ]; + serviceConfig = { + ExecStart = + "${pkgs.rss2email}/bin/r2e -c /var/rss2email/conf.cfg -d /var/rss2email/db.json run"; + User = "rss2email"; + PermissionsStartOnly = "true"; + }; + }; + + systemd.timers.rss2email = { + partOf = [ "rss2email.service" ]; + wantedBy = [ "timers.target" ]; + timerConfig.OnBootSec = "0"; + timerConfig.OnUnitActiveSec = cfg.interval; + }; + }; + + meta.maintainers = with lib.maintainers; [ ekleog ]; +} diff --git a/nixos/modules/services/monitoring/prometheus/alertmanager.nix b/nixos/modules/services/monitoring/prometheus/alertmanager.nix index 8a44cf7fd8f6..43b4a41eaf33 100644 --- a/nixos/modules/services/monitoring/prometheus/alertmanager.nix +++ b/nixos/modules/services/monitoring/prometheus/alertmanager.nix @@ -5,10 +5,18 @@ with lib; let cfg = config.services.prometheus.alertmanager; mkConfigFile = pkgs.writeText "alertmanager.yml" (builtins.toJSON cfg.configuration); - alertmanagerYml = - if cfg.configText != null then - pkgs.writeText "alertmanager.yml" cfg.configText - else mkConfigFile; + + checkedConfig = file: pkgs.runCommand "checked-config" { buildInputs = [ cfg.package ]; } '' + ln -s ${file} $out + amtool check-config $out + ''; + + alertmanagerYml = let + yml = if cfg.configText != null then + pkgs.writeText "alertmanager.yml" cfg.configText + else mkConfigFile; + in checkedConfig yml; + cmdlineArgs = cfg.extraFlags ++ [ "--config.file ${alertmanagerYml}" "--web.listen-address ${cfg.listenAddress}:${toString cfg.port}" @@ -23,6 +31,15 @@ in { services.prometheus.alertmanager = { enable = mkEnableOption "Prometheus Alertmanager"; + package = mkOption { + type = types.package; + default = pkgs.prometheus-alertmanager; + defaultText = "pkgs.alertmanager"; + description = '' + Package that should be used for alertmanager. + ''; + }; + user = mkOption { type = types.str; default = "nobody"; @@ -40,8 +57,8 @@ in { }; configuration = mkOption { - type = types.attrs; - default = {}; + type = types.nullOr types.attrs; + default = null; description = '' Alertmanager configuration as nix attribute set. ''; @@ -119,26 +136,34 @@ in { }; }; + config = mkMerge [ + (mkIf cfg.enable { + assertions = singleton { + assertion = cfg.configuration != null || cfg.configText != null; + message = "Can not enable alertmanager without a configuration. " + + "Set either the `configuration` or `configText` attribute."; + }; + }) + (mkIf cfg.enable { + networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; + + systemd.services.alertmanager = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + script = '' + ${cfg.package}/bin/alertmanager \ + ${concatStringsSep " \\\n " cmdlineArgs} + ''; - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; - - systemd.services.alertmanager = { - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - script = '' - ${pkgs.prometheus-alertmanager.bin}/bin/alertmanager \ - ${concatStringsSep " \\\n " cmdlineArgs} - ''; - - serviceConfig = { - User = cfg.user; - Group = cfg.group; - Restart = "always"; - PrivateTmp = true; - WorkingDirectory = "/tmp"; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + serviceConfig = { + User = cfg.user; + Group = cfg.group; + Restart = "always"; + PrivateTmp = true; + WorkingDirectory = "/tmp"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + }; }; - }; - }; + }) + ]; } diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 0d5a747b5c56..7bf261b58d66 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -179,6 +179,7 @@ in radicale = handleTest ./radicale.nix {}; redmine = handleTest ./redmine.nix {}; rspamd = handleTest ./rspamd.nix {}; + rss2email = handleTest ./rss2email.nix {}; rsyslogd = handleTest ./rsyslogd.nix {}; runInMachine = handleTest ./run-in-machine.nix {}; rxe = handleTest ./rxe.nix {}; diff --git a/nixos/tests/common/webroot/news-rss.xml b/nixos/tests/common/webroot/news-rss.xml new file mode 100644 index 000000000000..28e6fa7da1f3 --- /dev/null +++ b/nixos/tests/common/webroot/news-rss.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<rss xmlns:blogChannel="http://backend.userland.com/blogChannelModule" version="2.0"><channel><title>NixOS News</title><link>https://nixos.org</link><description>News for NixOS, the purely functional Linux distribution.</description><image><title>NixOS</title><url>https://nixos.org/logo/nixos-logo-only-hires.png</url><link>https://nixos.org/</link></image><item><title> + NixOS 18.09 released + </title><link>https://nixos.org/news.html</link><description> + <a href="https://github.com/NixOS/nixos-artwork/blob/master/releases/18.09-jellyfish/jellyfish.png"> + <img class="inline" src="logo/nixos-logo-18.09-jellyfish-lores.png" alt="18.09 Jellyfish logo" with="100" height="87"/> + </a> + NixOS 18.09 “Jellyfish” has been released, the tenth stable release branch. + See the <a href="/nixos/manual/release-notes.html#sec-release-18.09">release notes</a> + for details. You can get NixOS 18.09 ISOs and VirtualBox appliances + from the <a href="nixos/download.html">download page</a>. + For information on how to upgrade from older release branches + to 18.09, check out the + <a href="/nixos/manual/index.html#sec-upgrading">manual section on upgrading</a>. + </description><pubDate>Sat Oct 06 2018 00:00:00 GMT</pubDate></item></channel></rss> diff --git a/nixos/tests/prometheus.nix b/nixos/tests/prometheus.nix index 87a6510f40fd..f1b20a33d71e 100644 --- a/nixos/tests/prometheus.nix +++ b/nixos/tests/prometheus.nix @@ -13,6 +13,25 @@ import ./make-test.nix { }]; }]; rules = [ ''testrule = count(up{job="prometheus"})'' ]; + + # a very simple version of the alertmanager configuration just to see if + # configuration checks & service startup are working + alertmanager = { + enable = true; + listenAddress = "[::1]"; + port = 9093; + configuration = { + route.receiver = "webhook"; + receivers = [ + { + name = "webhook"; + webhook_configs = [ + { url = "http://localhost"; } + ]; + } + ]; + }; + }; }; }; }; @@ -22,5 +41,8 @@ import ./make-test.nix { $one->waitForUnit("prometheus.service"); $one->waitForOpenPort(9090); $one->succeed("curl -s http://127.0.0.1:9090/metrics"); + $one->waitForUnit("alertmanager.service"); + $one->waitForOpenPort("9093"); + $one->succeed("curl -f -s http://localhost:9093/"); ''; } diff --git a/nixos/tests/rss2email.nix b/nixos/tests/rss2email.nix new file mode 100644 index 000000000000..492d47da9f56 --- /dev/null +++ b/nixos/tests/rss2email.nix @@ -0,0 +1,66 @@ +import ./make-test.nix { + name = "opensmtpd"; + + nodes = { + server = { pkgs, ... }: { + imports = [ common/user-account.nix ]; + services.nginx = { + enable = true; + virtualHosts."127.0.0.1".root = ./common/webroot; + }; + services.rss2email = { + enable = true; + to = "alice@localhost"; + interval = "1"; + config.from = "test@example.org"; + feeds = { + nixos = { url = "http://127.0.0.1/news-rss.xml"; }; + }; + }; + services.opensmtpd = { + enable = true; + extraServerArgs = [ "-v" ]; + serverConfiguration = '' + listen on 127.0.0.1 + action dovecot_deliver mda \ + "${pkgs.dovecot}/libexec/dovecot/deliver -d %{user.username}" + match from any for local action dovecot_deliver + ''; + }; + services.dovecot2 = { + enable = true; + enableImap = true; + mailLocation = "maildir:~/mail"; + protocols = [ "imap" ]; + }; + environment.systemPackages = let + checkMailLanded = pkgs.writeScriptBin "check-mail-landed" '' + #!${pkgs.python3.interpreter} + import imaplib + + with imaplib.IMAP4('127.0.0.1', 143) as imap: + imap.login('alice', 'foobar') + imap.select() + status, refs = imap.search(None, 'ALL') + print("=====> Result of search for all:", status, refs) + assert status == 'OK' + assert len(refs) > 0 + status, msg = imap.fetch(refs[0], 'BODY[TEXT]') + assert status == 'OK' + ''; + in [ pkgs.opensmtpd checkMailLanded ]; + }; + }; + + testScript = '' + startAll; + + $server->waitForUnit("network-online.target"); + $server->waitForUnit("opensmtpd"); + $server->waitForUnit("dovecot2"); + $server->waitForUnit("nginx"); + $server->waitForUnit("rss2email"); + + $server->waitUntilSucceeds('check-mail-landed >&2'); + ''; +} |