Print zone name with details
[mirror/dsa-nagios.git] / dsa-nagios-checks / checks / dsa-check-zone-rrsig-expiration-many
1 #!/usr/bin/perl
2
3 # Copyright (c) 2010 Peter Palfrader <peter@palfrader.org>
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
12 #
13 # The above copyright notice and this permission notice shall be
14 # included in all copies or substantial portions of the Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 use strict;
25 use warnings;
26 use English;
27 use Getopt::Long;
28 use FindBin qw($Bin);
29
30 my $CHECK = $Bin.'/dsa-check-zone-rrsig-expiration';
31
32 $SIG{__DIE__} = sub {
33         print @_;
34         exit 3;
35 };
36
37 sub convert_time {
38         my $ticks = shift;
39         my $unit = shift;
40
41         unless (defined $unit) {
42                 my $newticks;
43                 ($newticks, $unit) = $ticks =~ m/^(\d*)([smhdw]?)$/;
44                 if (!defined $newticks) {
45                         print STDERR "Warning: invalid timestring to convert '$ticks'\n";
46                         return $ticks;
47                 }
48                 $ticks = $newticks;
49         }
50
51         if ($unit eq 's' || $unit eq '') { }
52         elsif ($unit eq 'm') { $ticks *= 60; }
53         elsif ($unit eq 'h') { $ticks *= 60*60; }
54         elsif ($unit eq 'd') { $ticks *= 60*60*24; }
55         elsif ($unit eq 'w') { $ticks *= 60*60*24*7; }
56         else { print STDERR "Warning: invalid unit '$unit'\n" }
57         return $ticks;
58 }
59
60 my $USAGE = "Usage: $PROGRAM_NAME [--help] | [--warn=<nn>] [--critical=<nn>] <indir>\n";
61 my $params = { 'warn' => '14d', 'critical' => '7d' };
62 Getopt::Long::config('bundling');
63 GetOptions (
64         '--help' => \$params->{'help'},
65         '--warn=s' => \$params->{'warn'},
66         '--critical=s' => \$params->{'critical'},
67 ) or die ($USAGE);
68 if ($params->{'help'}) {
69         print $USAGE;
70         exit(0);
71 };
72 die ($USAGE) unless (scalar @ARGV == 1);
73 my $INDIR = shift;
74
75
76 my @zones;
77 chdir $INDIR or die "chdir $INDIR failed? $!\n";
78 opendir INDIR, $INDIR or die ("Cannot opendir $INDIR\n");
79 for my $file (readdir INDIR) {
80         next if ( -l "$file" );
81         next unless ( -f "$file" );
82         next if $file =~ /^(dsset|keyset)-/;
83
84         push @zones, $file;
85 }
86 closedir(INDIR);
87
88
89 my $count =
90         { 'ok' => [],
91           'warn' => [],
92           'critical' => [],
93           'unknown' => [],
94           'unsigned' => [],
95         };
96
97 my @details;
98
99 for my $zone (sort {$a cmp $b} @zones) {
100         my $do_dnssec = 0;
101         open(F, '<', $zone) or die ("Cannot open $zone: $!\n");
102         for (<F>) {
103                 if (/^; wzf:\s*dnssec\s*=\s*1\s*$/) { $do_dnssec = 1; }
104         };
105         close F;
106
107         unless ($do_dnssec) {
108                 push @{$count->{'unsigned'}}, $zone;
109                 next;
110         };
111
112
113         open(P, '-|', ($CHECK, '-w', $params->{'warn'}, '-c', $params->{'critical'}, $zone)) or die ("Cannot run $CHECK for $zone\n");
114         my @p = <P>;
115         close P;
116         $p[0] = $zone.': '. $p[0] if (scalar @p > 0);
117         push @details, @p;
118
119         my $res = $CHILD_ERROR >> 8;
120         if ($res == 0) { push @{$count->{'ok'}}, $zone; }
121         elsif ($res == 1) { push @{$count->{'warn'}}, $zone; }
122         elsif ($res == 2) { push @{$count->{'critical'}}, $zone; }
123         else { push @{$count->{'unknown'}}, $zone; };
124 };
125
126 my $exit;
127 my %state_mapping = (
128         'unknown' => 255,
129         'critical' => 2,
130         'warn' => 1,
131         'ok' => 0 );
132
133 for my $state (sort {$state_mapping{$b} <=> $state_mapping{$a}} keys %state_mapping) {
134         if (scalar @{$count->{$state}}) {
135                 printf "%s: %d", uc($state), scalar @{$count->{$state}};
136                 if ($state_mapping{$state} > 0) {
137                         print ": ", join(', ', @{$count->{$state}});
138                 };
139                 print "; ";
140                 $exit = $state_mapping{$state} unless defined $exit;
141         };
142 };
143 printf "unsigned: %d", scalar @{$count->{'unsigned'}};
144 print "\n";
145 print $_ for (@details);
146 exit $exit;