blob: b7c3997dd9b10467fbc8f1d6249e43d2897ca32a (
plain) (
tree)
|
|
{
inputs = {
environment.url = "path:../environment";
secrets.url = "path:../../secrets";
naemon.url = "path:../../naemon";
nixpkgs-lib.url = "github:NixOS/nixpkgs?dir=lib";
};
outputs = { self, environment, nixpkgs-lib, secrets, naemon }: {
nagios-cli-config = ./nagios-cli.cfg;
lib = rec {
expandedObject = kind: object: objects:
if object ? "use"
then expandedObject kind objects.templates.${kind}.${object.use} objects // object
else object;
objectsCommon = import ./objects_common.nix;
toObjects = import ./to_objects.nix { inherit (nixpkgs-lib) lib; };
toMasterPassiveObject = svcTemplate: freshnessThresholdMultiplier: objects:
{
service = with nixpkgs-lib.lib; map (s:
{
host_name = (expandedObject "service" s objects).host_name;
use = svcTemplate;
retry_interval = "1";
freshness_threshold = let
fs = expandedObject "service" s objects;
in if builtins.isInt fs.check_interval
then builtins.ceil (freshnessThresholdMultiplier * 60 * fs.check_interval)
else fs.check_interval;
}
// filterAttrs (k: v: builtins.elem k ["service_description"] || builtins.substring 0 1 k == "_") s
// mapAttrs'
(n: nameValuePair (removePrefix "__passive_" n))
(filterAttrs (k: _: hasPrefix "__passive_" k) s)
) objects.service;
host = objects.host;
};
emailCheck = allCfg: host: hostFQDN: let
cfg = allCfg."${host}";
reverseTargets = builtins.attrNames (nixpkgs-lib.lib.filterAttrs (k: v: builtins.elem host v.targets) allCfg);
to_email = cfg': host':
let sep = if nixpkgs-lib.lib.hasInfix "+" cfg'.mail_address then "_" else "+";
in "${cfg'.mail_address}${sep}${host'}@${cfg'.mail_domain}";
mails_to_send = builtins.concatStringsSep "," (map (n: to_email allCfg."${n}" host) cfg.targets);
mails_to_receive = builtins.concatStringsSep "," (map (n: "${to_email cfg n}:${n}") reverseTargets);
command = if cfg.local
then
[ "check_emails_local" "/var/lib/naemon/checks/email" mails_to_send mails_to_receive ]
else
[ "check_emails" cfg.login cfg.port mails_to_send mails_to_receive ];
in
{
service_description = "${hostFQDN} email service is active";
use = "mail-service";
host_name = hostFQDN;
servicegroups = "webstatus-email";
check_command = command;
};
};
nixosModule = self.nixosModules.monitoring;
nixosModules.monitoring = { config, pkgs, lib, ... }:
let
cfg = config.myServices.monitoring;
allPluginsConfig = import ./myplugins.nix {
inherit pkgs lib config;
sudo = "/run/wrappers/bin/sudo";
};
mypluginsConfig = lib.mapAttrs (n: v:
if builtins.isFunction v
then v (cfg.pluginsArgs."${n}" or {})
else v
) (lib.getAttrs cfg.activatedPlugins allPluginsConfig);
myplugins = let
mypluginsChunk = builtins.concatStringsSep "\n" (lib.mapAttrsToList (k: v: v.chunk or "") mypluginsConfig);
in pkgs.runCommand "buildplugins" {
buildInputs = [ pkgs.makeWrapper pkgs.perl ];
} ''
mkdir $out
${mypluginsChunk}
'';
objectsModule = with lib.types; submodule {
options = {
command = lib.mkOption {
type = attrsOf str;
default = {};
description = "Command definitions";
};
host = lib.mkOption {
type = attrsOf (attrsOf str);
default = {};
description = "Host definitions";
};
hostgroup = lib.mkOption {
type = attrsOf (attrsOf str);
default = {};
description = "Host group definitions";
};
hostdependency = lib.mkOption {
type = listOf (attrsOf str);
default = [];
description = "Host dependency definitions";
};
service = lib.mkOption {
type = listOf (attrsOf (oneOf [ str (listOf str) int ]));
# str -> string
# listOf str -> list to be concatenated with "!"
# int -> toString
default = [];
description = "Service definitions";
};
servicegroup = lib.mkOption {
type = attrsOf (attrsOf str);
default = {};
description = "Service group definitions";
};
servicedependency = lib.mkOption {
type = listOf (attrsOf str);
default = [];
description = "Service dependency definitions";
};
contact = lib.mkOption {
type = attrsOf (attrsOf str);
default = {};
description = "Contact definitions";
};
contactgroup = lib.mkOption {
type = attrsOf (attrsOf str);
default = {};
description = "Contact group definitions";
};
timeperiod = lib.mkOption {
type = attrsOf (attrsOf str);
default = {};
description = "Time period definitions";
};
templates = lib.mkOption {
description = "Template definitions";
default = {};
type = submodule {
options = {
service = lib.mkOption { type = attrsOf (attrsOf (either str int)); default = {}; };
contact = lib.mkOption { type = attrsOf (attrsOf str); default = {}; };
host = lib.mkOption { type = attrsOf (attrsOf str); default = {}; };
};
};
};
};
};
in
{
options = {
myServices.monitoring = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable monitoring.
'';
};
master = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
This instance is the master instance
'';
};
pluginsArgs = lib.mkOption {
default = {};
description = "Arguments to pass to the naemon plugin configuration";
type = lib.types.attrsOf (lib.types.attrsOf lib.types.unspecified);
};
activatedPlugins = lib.mkOption {
default = [];
description = "List of naemon plugins to activate";
type = lib.types.listOf (lib.types.enum (builtins.attrNames allPluginsConfig));
};
fromMasterActivatedPlugins = lib.mkOption {
default = [];
description = "List of naemon plugins to activate from master";
type = lib.types.listOf (lib.types.str);
};
resources = lib.mkOption {
default = {};
description = "List of additionnal resources elements";
type = lib.types.attrsOf (lib.types.str);
};
objects = lib.mkOption {
default = {};
description = "Object definitions";
type = objectsModule;
};
fromMasterObjects = lib.mkOption {
default = {};
description = "Object definitions of checks that should be executed from master";
type = objectsModule;
};
};
};
imports = [
environment.nixosModule
secrets.nixosModule
naemon.nixosModule
];
config = lib.mkIf cfg.enable {
myServices.monitoring.objects.command =
lib.foldr (v: o: o // (v.commands or {})) {} (builtins.attrValues mypluginsConfig);
security.sudo.extraRules = let
pluginsSudo = lib.lists.remove null (lib.mapAttrsToList (k: v:
if (v ? sudo)
then ({ users = [ "naemon" ]; } // (v.sudo myplugins))
else null) mypluginsConfig);
in pluginsSudo;
environment.etc.cnagios.source = "${pkgs.cnagios}/share/doc/cnagios";
environment.systemPackages = let
nagios-cli = pkgs.writeScriptBin "nagios-cli" ''
#!${pkgs.stdenv.shell}
sudo -u naemon ${pkgs.nagios-cli}/bin/nagios-cli -c ${self.nagios-cli-config}
'';
in [
pkgs.cnagios
nagios-cli
];
secrets.keys = {
"naemon/id_rsa" = {
user = "naemon";
group = "naemon";
permissions = "0400";
text = config.myEnv.monitoring.ssh_secret_key;
};
"naemon/resources.cfg".keyDependencies = [ myplugins ];
};
services.naemon = {
enable = true;
extraConfig = ''
use_syslog=1
log_initial_states=1
date_format=iso8601
admin_email=${config.myEnv.monitoring.email}
'' + lib.optionalString (!cfg.master) ''
obsess_over_services=1
ocsp_command=notify-master
'';
extraResource = let
resources = [cfg.resources or {}] ++ (lib.mapAttrsToList (k: v: v.resources or {}) mypluginsConfig);
joined = lib.zipAttrsWith (n: v: if builtins.length (lib.unique v) == 1 then builtins.head v else abort "Non-unique resources names") resources;
joinedStr = builtins.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "$" + "${k}$=${v}") joined);
in ''
$USER2$=${myplugins}
${joinedStr}
'';
objectDefs =
self.lib.toObjects cfg.objects;
};
};
};
};
}
|