diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2020-01-17 01:15:04 +0100 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2020-01-17 01:15:04 +0100 |
commit | 71a2425ed95120a6de3a41bb233b1066779d4c26 (patch) | |
tree | 007f2756abab644604577352da28b1fd4c20df44 /modules/private/monitoring | |
parent | 981fa80354fd6f00f49446777c38f77bd8a65f65 (diff) | |
download | Nix-71a2425ed95120a6de3a41bb233b1066779d4c26.tar.gz Nix-71a2425ed95120a6de3a41bb233b1066779d4c26.tar.zst Nix-71a2425ed95120a6de3a41bb233b1066779d4c26.zip |
Add e-mail checks monitoring
Diffstat (limited to 'modules/private/monitoring')
-rw-r--r-- | modules/private/monitoring/default.nix | 54 | ||||
-rw-r--r-- | modules/private/monitoring/objects_common.nix | 2 | ||||
-rw-r--r-- | modules/private/monitoring/objects_eldiron.nix | 5 | ||||
-rw-r--r-- | modules/private/monitoring/objects_immae-eu.nix | 7 | ||||
-rw-r--r-- | modules/private/monitoring/objects_phare.nix | 11 | ||||
-rw-r--r-- | modules/private/monitoring/objects_ulminfo-fr.nix | 11 | ||||
-rwxr-xr-x | modules/private/monitoring/plugins/check_emails | 119 | ||||
-rwxr-xr-x | modules/private/monitoring/send_mails | 15 |
8 files changed, 189 insertions, 35 deletions
diff --git a/modules/private/monitoring/default.nix b/modules/private/monitoring/default.nix index e1357a7..a7013af 100644 --- a/modules/private/monitoring/default.nix +++ b/modules/private/monitoring/default.nix | |||
@@ -1,6 +1,16 @@ | |||
1 | { config, pkgs, lib, name, nodes, ... }: | 1 | { config, pkgs, lib, name, nodes, ... }: |
2 | let | 2 | let |
3 | cfg = config.myServices.monitoring; | 3 | cfg = config.myServices.monitoring; |
4 | send_mails = pkgs.runCommand "send_mails" { | ||
5 | buildInputs = [ pkgs.makeWrapper ]; | ||
6 | } '' | ||
7 | mkdir -p $out/bin | ||
8 | cp ${./send_mails} $out/bin/send_mails | ||
9 | patchShebangs $out | ||
10 | wrapProgram $out/bin/send_mails --prefix PATH : ${lib.makeBinPath [ | ||
11 | pkgs.mailutils | ||
12 | ]} | ||
13 | ''; | ||
4 | myplugins = pkgs.runCommand "buildplugins" { | 14 | myplugins = pkgs.runCommand "buildplugins" { |
5 | buildInputs = [ pkgs.makeWrapper pkgs.perl ]; | 15 | buildInputs = [ pkgs.makeWrapper pkgs.perl ]; |
6 | } '' | 16 | } '' |
@@ -29,6 +39,11 @@ let | |||
29 | wrapProgram $out/check_openldap_replication --prefix PATH : ${lib.makeBinPath [ | 39 | wrapProgram $out/check_openldap_replication --prefix PATH : ${lib.makeBinPath [ |
30 | pkgs.gnugrep pkgs.gnused pkgs.coreutils pkgs.openldap | 40 | pkgs.gnugrep pkgs.gnused pkgs.coreutils pkgs.openldap |
31 | ]} | 41 | ]} |
42 | wrapProgram $out/check_emails --prefix PATH : ${lib.makeBinPath [ | ||
43 | pkgs.openssh send_mails | ||
44 | ]} --prefix PERL5LIB : ${pkgs.perlPackages.makePerlPath [ | ||
45 | pkgs.perlPackages.TimeDate | ||
46 | ]} | ||
32 | wrapProgram $out/check_ftp_database --prefix PATH : ${lib.makeBinPath [ | 47 | wrapProgram $out/check_ftp_database --prefix PATH : ${lib.makeBinPath [ |
33 | pkgs.lftp | 48 | pkgs.lftp |
34 | ]} | 49 | ]} |
@@ -67,11 +82,6 @@ let | |||
67 | }; | 82 | }; |
68 | }; | 83 | }; |
69 | masterPassiveObjects = let | 84 | masterPassiveObjects = let |
70 | otherPassiveObjects = map | ||
71 | (n: (pkgs.callPackage (./. + "/objects_" + n + ".nix") {})) | ||
72 | [ "caldance-1" "ulminfo-fr" "immae-eu" "phare" "tiboqorl-fr" ]; | ||
73 | otherPassiveServices = lib.flatten (map (h: h.service or []) otherPassiveObjects); | ||
74 | otherPassiveHosts = (map (h: h.host)) otherPassiveObjects; | ||
75 | passiveNodes = lib.attrsets.filterAttrs (n: _: builtins.elem n ["backup-2" "eldiron"]) nodes; | 85 | passiveNodes = lib.attrsets.filterAttrs (n: _: builtins.elem n ["backup-2" "eldiron"]) nodes; |
76 | toPassiveServices = map (s: s.passiveInfo.filter s // s.passiveInfo); | 86 | toPassiveServices = map (s: s.passiveInfo.filter s // s.passiveInfo); |
77 | passiveServices = lib.flatten (lib.attrsets.mapAttrsToList | 87 | passiveServices = lib.flatten (lib.attrsets.mapAttrsToList |
@@ -79,12 +89,37 @@ let | |||
79 | passiveNodes | 89 | passiveNodes |
80 | ); | 90 | ); |
81 | in { | 91 | in { |
82 | service = passiveServices ++ otherPassiveServices; | 92 | service = passiveServices; |
83 | host = lib.lists.foldr | 93 | host = lib.lists.foldr |
84 | (a: b: a//b) | 94 | (a: b: a//b) |
85 | {} | 95 | {} |
86 | (otherPassiveHosts ++ lib.attrsets.mapAttrsToList (_: h: h.config.myServices.monitoring.hosts) passiveNodes); | 96 | (lib.attrsets.mapAttrsToList (_: h: h.config.myServices.monitoring.hosts) passiveNodes); |
87 | }; | 97 | }; |
98 | emailCheck = host: hostFQDN: let | ||
99 | allCfg = config.myEnv.monitoring.email_check; | ||
100 | cfg = allCfg."${host}"; | ||
101 | reverseTargets = builtins.attrNames (lib.attrsets.filterAttrs (k: v: builtins.elem host v.targets) allCfg); | ||
102 | to_email = cfg': host': | ||
103 | let sep = if lib.strings.hasInfix "+" cfg'.mail_address then "_" else "+"; | ||
104 | in "${cfg'.mail_address}${sep}${host'}@${cfg'.mail_domain}"; | ||
105 | mails_to_send = builtins.concatStringsSep "," (map (n: to_email allCfg."${n}" host) cfg.targets); | ||
106 | mails_to_receive = builtins.concatStringsSep "," (map (n: "${to_email cfg n}:${n}") reverseTargets); | ||
107 | command = if cfg.local | ||
108 | then | ||
109 | [ "check_emails_local" "/var/lib/naemon/checks/email" mails_to_send mails_to_receive ] | ||
110 | else | ||
111 | [ "check_emails" cfg.login cfg.port mails_to_send mails_to_receive ]; | ||
112 | in | ||
113 | { | ||
114 | service_description = "${hostFQDN} email service is active"; | ||
115 | use = "mail-service"; | ||
116 | host_name = hostFQDN; | ||
117 | servicegroups = "webstatus-email"; | ||
118 | check_command = command; | ||
119 | }; | ||
120 | otherObjects = map | ||
121 | (n: (pkgs.callPackage (./. + "/objects_" + n + ".nix") { inherit emailCheck; })) | ||
122 | [ "caldance-1" "ulminfo-fr" "immae-eu" "phare" "tiboqorl-fr" ]; | ||
88 | masterObjects = pkgs.callPackage ./objects_master.nix { inherit config; }; | 123 | masterObjects = pkgs.callPackage ./objects_master.nix { inherit config; }; |
89 | commonObjects = pkgs.callPackage ./objects_common.nix ({ | 124 | commonObjects = pkgs.callPackage ./objects_common.nix ({ |
90 | master = cfg.master; | 125 | master = cfg.master; |
@@ -99,7 +134,7 @@ let | |||
99 | lib.attrsets.optionalAttrs | 134 | lib.attrsets.optionalAttrs |
100 | (builtins.pathExists specific_file) | 135 | (builtins.pathExists specific_file) |
101 | (pkgs.callPackage specific_file { | 136 | (pkgs.callPackage specific_file { |
102 | inherit config; | 137 | inherit config emailCheck; |
103 | hostFQDN = config.hostEnv.fqdn; | 138 | hostFQDN = config.hostEnv.fqdn; |
104 | hostName = name; | 139 | hostName = name; |
105 | }); | 140 | }); |
@@ -228,7 +263,8 @@ in | |||
228 | objectDefs = toObjects commonObjects | 263 | objectDefs = toObjects commonObjects |
229 | + toObjects hostObjects | 264 | + toObjects hostObjects |
230 | + lib.optionalString cfg.master (toObjects masterObjects) | 265 | + lib.optionalString cfg.master (toObjects masterObjects) |
231 | + lib.optionalString cfg.master (toObjects masterPassiveObjects); | 266 | + lib.optionalString cfg.master (toObjects masterPassiveObjects) |
267 | + lib.optionalString cfg.master (builtins.concatStringsSep "\n" (map toObjects otherObjects)); | ||
232 | }; | 268 | }; |
233 | }; | 269 | }; |
234 | } | 270 | } |
diff --git a/modules/private/monitoring/objects_common.nix b/modules/private/monitoring/objects_common.nix index 15eee97..a9d6da4 100644 --- a/modules/private/monitoring/objects_common.nix +++ b/modules/private/monitoring/objects_common.nix | |||
@@ -91,6 +91,8 @@ in | |||
91 | ]; | 91 | ]; |
92 | command = { | 92 | command = { |
93 | check_dns = "$USER1$/check_dns -H $ARG1$ -s $HOSTADDRESS$ $ARG2$"; | 93 | check_dns = "$USER1$/check_dns -H $ARG1$ -s $HOSTADDRESS$ $ARG2$"; |
94 | check_emails = "$USER2$/check_emails -H $HOSTADDRESS$ -i $USER203$ -l $ARG1$ -p $ARG2$ -s $ARG3$ -f $ARG4$"; | ||
95 | check_emails_local = "$USER2$/check_emails -H $HOSTADDRESS$ -n $ARG1$ -r $ADMINEMAIL$ -s $ARG2$ -f $ARG3$"; | ||
94 | check_eriomem = "$USER2$/check_eriomem $USER208$"; | 96 | check_eriomem = "$USER2$/check_eriomem $USER208$"; |
95 | check_external_dns = "$USER1$/check_dns -H $ARG2$ -s $ARG1$ $ARG3$"; | 97 | check_external_dns = "$USER1$/check_dns -H $ARG2$ -s $ARG1$ $ARG3$"; |
96 | check_ftp_database = "$USER2$/check_ftp_database"; | 98 | check_ftp_database = "$USER2$/check_ftp_database"; |
diff --git a/modules/private/monitoring/objects_eldiron.nix b/modules/private/monitoring/objects_eldiron.nix index bee4645..92f997f 100644 --- a/modules/private/monitoring/objects_eldiron.nix +++ b/modules/private/monitoring/objects_eldiron.nix | |||
@@ -1,4 +1,4 @@ | |||
1 | { lib, hostFQDN, ... }: | 1 | { lib, hostFQDN, emailCheck, ... }: |
2 | let | 2 | let |
3 | defaultPassiveInfo = { | 3 | defaultPassiveInfo = { |
4 | filter = lib.attrsets.filterAttrs | 4 | filter = lib.attrsets.filterAttrs |
@@ -24,5 +24,8 @@ in | |||
24 | use = "local-service"; | 24 | use = "local-service"; |
25 | check_command = ["check_mailq"]; | 25 | check_command = ["check_mailq"]; |
26 | } | 26 | } |
27 | (emailCheck "eldiron" hostFQDN // { | ||
28 | passiveInfo = defaultPassiveInfo // { servicegroups = "webstatus-email"; freshness_threshold = "1350"; }; | ||
29 | }) | ||
27 | ]; | 30 | ]; |
28 | } | 31 | } |
diff --git a/modules/private/monitoring/objects_immae-eu.nix b/modules/private/monitoring/objects_immae-eu.nix index a6337e9..cffb180 100644 --- a/modules/private/monitoring/objects_immae-eu.nix +++ b/modules/private/monitoring/objects_immae-eu.nix | |||
@@ -84,12 +84,5 @@ in | |||
84 | service_description = "mailq is empty"; | 84 | service_description = "mailq is empty"; |
85 | servicegroups = "webstatus-email"; | 85 | servicegroups = "webstatus-email"; |
86 | } | 86 | } |
87 | |||
88 | ## Sending e-mail | ||
89 | { | ||
90 | service_description = "immae.eu email service is active"; | ||
91 | servicegroups = "webstatus-email"; | ||
92 | freshness_threshold = "1350"; | ||
93 | } | ||
94 | ]; | 87 | ]; |
95 | } | 88 | } |
diff --git a/modules/private/monitoring/objects_phare.nix b/modules/private/monitoring/objects_phare.nix index ab46436..a00e5e8 100644 --- a/modules/private/monitoring/objects_phare.nix +++ b/modules/private/monitoring/objects_phare.nix | |||
@@ -1,4 +1,4 @@ | |||
1 | { ... }: | 1 | { emailCheck, ... }: |
2 | { | 2 | { |
3 | host = { | 3 | host = { |
4 | "phare.normalesup.org" = { | 4 | "phare.normalesup.org" = { |
@@ -10,13 +10,6 @@ | |||
10 | }; | 10 | }; |
11 | }; | 11 | }; |
12 | service = [ | 12 | service = [ |
13 | { | 13 | (emailCheck "phare" "phare.normalesup.org") |
14 | service_description = "phare.normalesup.org email service is active"; | ||
15 | use = "external-passive-service"; | ||
16 | host_name = "phare.normalesup.org"; | ||
17 | freshness_threshold = "1350"; | ||
18 | retry_interval = "1"; | ||
19 | servicegroups = "webstatus-email"; | ||
20 | } | ||
21 | ]; | 14 | ]; |
22 | } | 15 | } |
diff --git a/modules/private/monitoring/objects_ulminfo-fr.nix b/modules/private/monitoring/objects_ulminfo-fr.nix index 87a3e05..b970ecd 100644 --- a/modules/private/monitoring/objects_ulminfo-fr.nix +++ b/modules/private/monitoring/objects_ulminfo-fr.nix | |||
@@ -1,4 +1,4 @@ | |||
1 | { ... }: | 1 | { emailCheck, ... }: |
2 | { | 2 | { |
3 | host = { | 3 | host = { |
4 | "ulminfo.fr" = { | 4 | "ulminfo.fr" = { |
@@ -10,13 +10,6 @@ | |||
10 | }; | 10 | }; |
11 | }; | 11 | }; |
12 | service = [ | 12 | service = [ |
13 | { | 13 | (emailCheck "ulminfo" "ulminfo.fr") |
14 | service_description = "ulminfo.fr email service is active"; | ||
15 | use = "external-passive-service"; | ||
16 | host_name = "ulminfo.fr"; | ||
17 | freshness_threshold = "1350"; | ||
18 | retry_interval = "1"; | ||
19 | servicegroups = "webstatus-email"; | ||
20 | } | ||
21 | ]; | 14 | ]; |
22 | } | 15 | } |
diff --git a/modules/private/monitoring/plugins/check_emails b/modules/private/monitoring/plugins/check_emails new file mode 100755 index 0000000..0ee3e4e --- /dev/null +++ b/modules/private/monitoring/plugins/check_emails | |||
@@ -0,0 +1,119 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | use strict; | ||
4 | use Getopt::Std; | ||
5 | use File::Basename; | ||
6 | use Date::Parse; | ||
7 | use POSIX qw(strftime); | ||
8 | |||
9 | $| = 1; | ||
10 | |||
11 | my %opts; | ||
12 | getopts('hH:l:s:p:f:i:n:r:', \%opts); | ||
13 | |||
14 | my $STATE_OK = 0; | ||
15 | my $STATE_WARNING = 1; | ||
16 | my $STATE_CRITICAL = 2; | ||
17 | my $STATE_UNKNOWN = 3; | ||
18 | |||
19 | if ($opts{'h'} || scalar(%opts) == 0) { | ||
20 | &print_help(); | ||
21 | exit($STATE_OK); | ||
22 | } | ||
23 | |||
24 | my $port = $opts{'p'}; | ||
25 | my $host = $opts{'H'}; | ||
26 | my $login = $opts{'l'}; | ||
27 | if ($login ne '') { | ||
28 | $login = "$login@"; | ||
29 | } | ||
30 | |||
31 | my $identity = $opts{'i'}; | ||
32 | my $local_directory = $opts{'n'}; | ||
33 | my $return_path = $opts{'r'}; | ||
34 | |||
35 | my @emails_to_send = split(/,/, $opts{'s'}); | ||
36 | my @emails_to_expect = split(/,/, $opts{'f'}); | ||
37 | |||
38 | my $cmd_result; | ||
39 | if ($local_directory ne '') { | ||
40 | if (! -d $local_directory) { | ||
41 | print "Emails $host UNKNOWN - Could not find local directory"; | ||
42 | exit($STATE_UNKNOWN); | ||
43 | } | ||
44 | $cmd_result = `send_mails $local_directory $return_path @emails_to_send 2>&1`; | ||
45 | } else { | ||
46 | $cmd_result = `ssh -o BatchMode=yes -o UserKnownHostsFile=/dev/null -o CheckHostIP=no -o StrictHostKeyChecking=no -p $port -i $identity $login$host send_mails @emails_to_send 2>&1`; | ||
47 | |||
48 | if ($cmd_result =~ /Host key verification failed./) { | ||
49 | print "Emails $host UNKNOWN - Could not connect to host with ssh key\n"; | ||
50 | exit($STATE_UNKNOWN); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | my @lines = split(/\n/, $cmd_result); | ||
55 | |||
56 | my %found_emails; | ||
57 | |||
58 | foreach my $line (@lines) { | ||
59 | my @split_line = split(/;/, $line, 2); | ||
60 | $found_emails{$split_line[0]} = $split_line[1]; | ||
61 | } | ||
62 | |||
63 | my $output = ""; | ||
64 | foreach my $email_from (@emails_to_expect) { | ||
65 | my @email_split = split(/:/, $email_from); | ||
66 | my $email = $email_split[0]; | ||
67 | my $from = $email_split[1]; | ||
68 | |||
69 | if ( exists $found_emails{$email} ) { | ||
70 | my $email_date = str2time($found_emails{$email}); | ||
71 | my $current_date = strftime "%s", localtime; | ||
72 | |||
73 | if ($current_date - $email_date > 60*30) { | ||
74 | $output = "$output$email ($found_emails{$email} from $from) "; | ||
75 | } | ||
76 | } else { | ||
77 | $output = "$output$email (missing) " | ||
78 | } | ||
79 | } | ||
80 | |||
81 | if ($output ne '') { | ||
82 | print "Emails $host CRITICAL - expecting emails: $output\n"; | ||
83 | exit($STATE_CRITICAL); | ||
84 | } else { | ||
85 | print "Emails $host OK\n"; | ||
86 | exit($STATE_OK); | ||
87 | } | ||
88 | |||
89 | sub print_help() { | ||
90 | print << "EOF"; | ||
91 | Check sent emails | ||
92 | |||
93 | Options: | ||
94 | -h | ||
95 | Print detailed help screen | ||
96 | |||
97 | -H | ||
98 | Host to check | ||
99 | |||
100 | -l | ||
101 | Login | ||
102 | |||
103 | -i | ||
104 | Identity file | ||
105 | |||
106 | -n | ||
107 | Don’t use ssh, pass that directory to script | ||
108 | |||
109 | -r | ||
110 | Return path for local e-mails | ||
111 | |||
112 | -s | ||
113 | Comma separated list of emails to send from the host. | ||
114 | |||
115 | -f | ||
116 | Comma separated list of emails to expect on the host. | ||
117 | EOF | ||
118 | } | ||
119 | |||
diff --git a/modules/private/monitoring/send_mails b/modules/private/monitoring/send_mails new file mode 100755 index 0000000..105c505 --- /dev/null +++ b/modules/private/monitoring/send_mails | |||
@@ -0,0 +1,15 @@ | |||
1 | #!/usr/bin/env bash | ||
2 | |||
3 | CHECK_DIR=$1 | ||
4 | shift | ||
5 | RETURN_PATH=$1 | ||
6 | shift | ||
7 | |||
8 | for mail in "$@"; do | ||
9 | echo "Test Mail" | MAILRC=/dev/null mail -n -r "$RETURN_PATH" -s "TestMailImmae " "$mail" | ||
10 | done | ||
11 | |||
12 | if [ -d "$CHECK_DIR" ]; then | ||
13 | cd $CHECK_DIR | ||
14 | stat -c '%n;%y' * | ||
15 | fi | ||