diff options
Diffstat (limited to 'nixos/modules/services/networking/smokeping.nix')
-rw-r--r-- | nixos/modules/services/networking/smokeping.nix | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/nixos/modules/services/networking/smokeping.nix b/nixos/modules/services/networking/smokeping.nix new file mode 100644 index 00000000000..bd71b158dbe --- /dev/null +++ b/nixos/modules/services/networking/smokeping.nix @@ -0,0 +1,362 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + + cfg = config.services.smokeping; + smokepingHome = "/var/lib/smokeping"; + smokepingPidDir = "/run"; + configFile = + if cfg.config == null + then + '' + *** General *** + cgiurl = ${cfg.cgiUrl} + contact = ${cfg.ownerEmail} + datadir = ${smokepingHome}/data + imgcache = ${smokepingHome}/cache + imgurl = ${cfg.imgUrl} + linkstyle = ${cfg.linkStyle} + ${lib.optionalString (cfg.mailHost != "") "mailhost = ${cfg.mailHost}"} + owner = ${cfg.owner} + pagedir = ${smokepingHome}/cache + piddir = ${smokepingPidDir} + ${lib.optionalString (cfg.sendmail != null) "sendmail = ${cfg.sendmail}"} + smokemail = ${cfg.smokeMailTemplate} + *** Presentation *** + template = ${cfg.presentationTemplate} + ${cfg.presentationConfig} + *** Alerts *** + ${cfg.alertConfig} + *** Database *** + ${cfg.databaseConfig} + *** Probes *** + ${cfg.probeConfig} + *** Targets *** + ${cfg.targetConfig} + ${cfg.extraConfig} + '' + else + cfg.config; + + configPath = pkgs.writeText "smokeping.conf" configFile; + cgiHome = pkgs.writeScript "smokeping.fcgi" '' + #!${pkgs.bash}/bin/bash + ${cfg.package}/bin/smokeping_cgi ${configPath} + ''; +in + +{ + options = { + services.smokeping = { + enable = mkOption { + type = types.bool; + default = false; + description = "Enable the smokeping service"; + }; + alertConfig = mkOption { + type = types.lines; + default = '' + to = root@localhost + from = smokeping@localhost + ''; + example = '' + to = alertee@address.somewhere + from = smokealert@company.xy + + +someloss + type = loss + # in percent + pattern = >0%,*12*,>0%,*12*,>0% + comment = loss 3 times in a row; + ''; + description = "Configuration for alerts."; + }; + cgiUrl = mkOption { + type = types.str; + default = "http://${cfg.hostName}:${toString cfg.port}/smokeping.cgi"; + defaultText = literalExpression ''"http://''${hostName}:''${toString port}/smokeping.cgi"''; + example = "https://somewhere.example.com/smokeping.cgi"; + description = "URL to the smokeping cgi."; + }; + config = mkOption { + type = types.nullOr types.lines; + default = null; + description = "Full smokeping config supplied by the user. Overrides " + + "and replaces any other configuration supplied."; + }; + databaseConfig = mkOption { + type = types.lines; + default = '' + step = 300 + pings = 20 + # consfn mrhb steps total + AVERAGE 0.5 1 1008 + AVERAGE 0.5 12 4320 + MIN 0.5 12 4320 + MAX 0.5 12 4320 + AVERAGE 0.5 144 720 + MAX 0.5 144 720 + MIN 0.5 144 720 + + ''; + example = '' + # near constant pings. + step = 30 + pings = 20 + # consfn mrhb steps total + AVERAGE 0.5 1 10080 + AVERAGE 0.5 12 43200 + MIN 0.5 12 43200 + MAX 0.5 12 43200 + AVERAGE 0.5 144 7200 + MAX 0.5 144 7200 + MIN 0.5 144 7200 + ''; + description = ''Configure the ping frequency and retention of the rrd files. + Once set, changing the interval will require deletion or migration of all + the collected data.''; + }; + extraConfig = mkOption { + type = types.lines; + default = ""; + description = "Any additional customization not already included."; + }; + hostName = mkOption { + type = types.str; + default = config.networking.fqdn; + defaultText = literalExpression "config.networking.fqdn"; + example = "somewhere.example.com"; + description = "DNS name for the urls generated in the cgi."; + }; + imgUrl = mkOption { + type = types.str; + default = "cache"; + defaultText = literalExpression ''"cache"''; + example = "https://somewhere.example.com/cache"; + description = '' + Base url for images generated in the cgi. + + The default is a relative URL to ensure it works also when e.g. forwarding + the GUI port via SSH. + ''; + }; + linkStyle = mkOption { + type = types.enum ["original" "absolute" "relative"]; + default = "relative"; + example = "absolute"; + description = "DNS name for the urls generated in the cgi."; + }; + mailHost = mkOption { + type = types.str; + default = ""; + example = "localhost"; + description = "Use this SMTP server to send alerts"; + }; + owner = mkOption { + type = types.str; + default = "nobody"; + example = "Joe Admin"; + description = "Real name of the owner of the instance"; + }; + ownerEmail = mkOption { + type = types.str; + default = "no-reply@${cfg.hostName}"; + defaultText = literalExpression ''"no-reply@''${hostName}"''; + example = "no-reply@yourdomain.com"; + description = "Email contact for owner"; + }; + package = mkOption { + type = types.package; + default = pkgs.smokeping; + defaultText = literalExpression "pkgs.smokeping"; + description = "Specify a custom smokeping package"; + }; + host = mkOption { + type = types.nullOr types.str; + default = "localhost"; + example = "192.0.2.1"; # rfc5737 example IP for documentation + description = '' + Host/IP to bind to for the web server. + + Setting it to <literal>null</literal> skips passing the -h option to thttpd, + which makes it bind to all interfaces. + ''; + }; + port = mkOption { + type = types.int; + default = 8081; + description = "TCP port to use for the web server."; + }; + presentationConfig = mkOption { + type = types.lines; + default = '' + + charts + menu = Charts + title = The most interesting destinations + ++ stddev + sorter = StdDev(entries=>4) + title = Top Standard Deviation + menu = Std Deviation + format = Standard Deviation %f + ++ max + sorter = Max(entries=>5) + title = Top Max Roundtrip Time + menu = by Max + format = Max Roundtrip Time %f seconds + ++ loss + sorter = Loss(entries=>5) + title = Top Packet Loss + menu = Loss + format = Packets Lost %f + ++ median + sorter = Median(entries=>5) + title = Top Median Roundtrip Time + menu = by Median + format = Median RTT %f seconds + + overview + width = 600 + height = 50 + range = 10h + + detail + width = 600 + height = 200 + unison_tolerance = 2 + "Last 3 Hours" 3h + "Last 30 Hours" 30h + "Last 10 Days" 10d + "Last 360 Days" 360d + ''; + description = "presentation graph style"; + }; + presentationTemplate = mkOption { + type = types.str; + default = "${pkgs.smokeping}/etc/basepage.html.dist"; + defaultText = literalExpression ''"''${pkgs.smokeping}/etc/basepage.html.dist"''; + description = "Default page layout for the web UI."; + }; + probeConfig = mkOption { + type = types.lines; + default = '' + + FPing + binary = ${config.security.wrapperDir}/fping + ''; + defaultText = literalExpression '' + ''' + + FPing + binary = ''${config.security.wrapperDir}/fping + ''' + ''; + description = "Probe configuration"; + }; + sendmail = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/wrappers/bin/sendmail"; + description = "Use this sendmail compatible script to deliver alerts"; + }; + smokeMailTemplate = mkOption { + type = types.str; + default = "${cfg.package}/etc/smokemail.dist"; + defaultText = literalExpression ''"''${package}/etc/smokemail.dist"''; + description = "Specify the smokemail template for alerts."; + }; + targetConfig = mkOption { + type = types.lines; + default = '' + probe = FPing + menu = Top + title = Network Latency Grapher + remark = Welcome to the SmokePing website of xxx Company. \ + Here you will learn all about the latency of our network. + + Local + menu = Local + title = Local Network + ++ LocalMachine + menu = Local Machine + title = This host + host = localhost + ''; + description = "Target configuration"; + }; + user = mkOption { + type = types.str; + default = "smokeping"; + description = "User that runs smokeping and (optionally) thttpd. A group of the same name will be created as well."; + }; + webService = mkOption { + type = types.bool; + default = true; + description = "Enable a smokeping web interface"; + }; + }; + + }; + + config = mkIf cfg.enable { + assertions = [ + { + assertion = !(cfg.sendmail != null && cfg.mailHost != ""); + message = "services.smokeping: sendmail and Mailhost cannot both be enabled."; + } + ]; + security.wrappers = { + fping = + { setuid = true; + owner = "root"; + group = "root"; + source = "${pkgs.fping}/bin/fping"; + }; + }; + environment.systemPackages = [ pkgs.fping ]; + users.users.${cfg.user} = { + isNormalUser = false; + isSystemUser = true; + group = cfg.user; + description = "smokeping daemon user"; + home = smokepingHome; + createHome = true; + }; + users.groups.${cfg.user} = {}; + systemd.services.smokeping = { + requiredBy = [ "multi-user.target"]; + serviceConfig = { + User = cfg.user; + Restart = "on-failure"; + ExecStart = "${cfg.package}/bin/smokeping --config=${configPath} --nodaemon"; + }; + preStart = '' + mkdir -m 0755 -p ${smokepingHome}/cache ${smokepingHome}/data + rm -f ${smokepingHome}/cropper + ln -s ${cfg.package}/htdocs/cropper ${smokepingHome}/cropper + rm -f ${smokepingHome}/smokeping.fcgi + ln -s ${cgiHome} ${smokepingHome}/smokeping.fcgi + ${cfg.package}/bin/smokeping --check --config=${configPath} + ${cfg.package}/bin/smokeping --static --config=${configPath} + ''; + }; + systemd.services.thttpd = mkIf cfg.webService { + requiredBy = [ "multi-user.target"]; + requires = [ "smokeping.service"]; + path = with pkgs; [ bash rrdtool smokeping thttpd ]; + serviceConfig = { + Restart = "always"; + ExecStart = lib.concatStringsSep " " (lib.concatLists [ + [ "${pkgs.thttpd}/bin/thttpd" ] + [ "-u ${cfg.user}" ] + [ ''-c "**.fcgi"'' ] + [ "-d ${smokepingHome}" ] + (lib.optional (cfg.host != null) "-h ${cfg.host}") + [ "-p ${builtins.toString cfg.port}" ] + [ "-D -nos" ] + ]); + }; + }; + }; + + meta.maintainers = with lib.maintainers; [ + erictapen + nh2 + ]; +} + |