Set User-Agent in dsa-check-mirrorsync
[mirror/dsa-nagios.git] / dsa-nagios-checks / checks / dsa-check-mirrorsync
index af37983..c2445f1 100755 (executable)
@@ -3,7 +3,7 @@
 # nagios check for debian security sync checks
 #
 #  Copyright (c) 2008 Alexander Wirt <formorer@debian.org>
-#  Copyright (c) 2009 Peter Palfrader <peter@palfrader.org>
+#  Copyright (c) 2009, 2010, 2016 Peter Palfrader <peter@palfrader.org>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -45,10 +45,18 @@ sub usage($$) {
        print $fh "  --verbose           Be a little verbose.\n";
        print $fh "  --host              hostname to check.\n";
        print $fh "  --path              path to tracefile.\n";
+       print $fh "  --unix              tracefile has a unix timestamp.\n";
+       print $fh "  --ssl               use https.\n";
+       print $fh "  --allow-skew=<foo>:<bar> if the newest timestamp is newer than <foo>secs\n";
+       print $fh "                      then the mirror sync is still ok, assuming the oldest\n";
+       print $fh "                      trace file is no older than <bar>\n";
        print $fh "\n";
        exit ($exit);
 };
 
+# Work around LWP not being able to verify service certs directly
+my $ca_dir = '/etc/ssl/ca-debian';
+$ENV{'PERL_LWP_SSL_CA_PATH'} = $ca_dir if -d $ca_dir;
 
 $ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
 delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
@@ -67,14 +75,26 @@ if (!GetOptions (
                 '--help'                => \$params->{'help'},
                 '--verbose'             => \$params->{'verbose'},
                 '--version'             => \$params->{'version'},
+                '--unix'                => \$params->{'unix'},
+                '--ssl'                 => \$params->{'ssl'},
                 '--host=s'              => \$params->{'host'},
                 '--path=s'              => \$params->{'path'},
+                '--allow-skew=s'        => \$params->{'skew'},
                 )) {
                 usage(*STDERR,1)
 };
 usage(*STDOUT,0) if ($params->{'help'});
 usage(*STDERR,1) if (scalar @ARGV);
 
+if (defined $params->{'skew'}) {
+       if (not $params->{'skew'} =~ /^([0-9]+):([0-9]+)$/) {
+               print STDERR "Invalid allow-skew format\n";
+               usage(*STDERR,1);
+       };
+       $params->{'skew-new'} = $1;
+       $params->{'skew-old'} = $2;
+};
+
 my $host = $params->{'host'};
 my $path = $params->{'path'};
 my @slaves;
@@ -87,29 +107,42 @@ my $exitcode = $OK;
 print "Checking the following hosts:\n" . join("\n", @slaves) . "\n" if $params->{'verbose'};
 
 my @critical;
+my $schema = $params->{'ssl'} ? 'https' : 'http';
 
 foreach my $slave (@slaves) {
        my $ua = LWP::UserAgent->new;
-       $ua->proxy('http', "http://$slave");
-       print "Requesting http://$host/$path from $slave\n" if $params->{'verbose'};
-       my $response = $ua->get("http://$host/$path");
+       $ua->agent("dsa-check-mirrorsync");
+       $ua->timeout(10);
+       $ua->proxy('http', "$schema://$slave");
+       print "Requesting $schema://$host/$path from $slave\n" if $params->{'verbose'};
+       my $response = $ua->get("$schema://$host/$path");
 
 
        if ($response->is_success) {
                my $content = $response->content;  # or whatever
                my ($date, $foo, $bar) = split("\n", $content);
-               my $synctime = str2time($date);;
-               if (! defined $synctime) {
+               my $synctime;
+
+               if ($params->{'unix'}) {
+                       if ($date =~ /^([0-9]+)$/) {
+                               $synctime = $1;
+                       }
+               } else {
+                       $synctime = str2time($date);
+               }
+
+               if (defined $synctime) {
+                       print "$slave last synced $synctime ", scalar(gmtime($synctime)), "\n" if $params->{'verbose'};
+                       $status->{$slave}->{'synced'} = $synctime;
+               } else {
                        $synctime = 0;
                        $exitcode = $UNKNOWN;
                        push @exitstatus, "Cannot parse tracefile on $slave";
-               };
-               print "$slave last synced $synctime\n" if $params->{'verbose'};
-               $status->{$slave}->{'synced'} = $synctime;
-       }
-       else {
+               }
+       } else {
                push @exitstatus, "$slave broken: " . $response->status_line; 
                $status->{$slave}->{'error'} = $response->status_line;
+               $status->{$slave}->{'synced'} = 0;
                $exitcode = $CRITICAL;
                push @critical, $slave;
        }
@@ -119,22 +152,40 @@ foreach my $slave (@slaves) {
 my %seen;
 my $o_sync = scalar(grep !$seen{$_}++, map{$status->{$_}->{'synced'}} keys(%{$status}));
 if ($o_sync > 1) {
-       $exitcode = $CRITICAL; 
        my @mirrors =  sort { $status->{$a}->{'synced'} <=> $status->{$b}->{'synced'}  } keys %{$status};
        my @not_most_recent = grep { $status->{$_}->{'synced'} <=> $status->{$mirrors[-1]}->{'synced'} } @mirrors;
        $o_sync = scalar @not_most_recent;
-       push @exitstatus, "$o_sync mirror(s) not in sync (from oldest to newest): ".
-               join(", ", @not_most_recent);
+
+       my $newest = time - $status->{$mirrors[-1]}->{'synced'};
+       my $oldest = time - $status->{$mirrors[0]}->{'synced'};
+       my $skew_ok = ( defined $params->{'skew-new'} &&
+                       defined $params->{'skew-old'} &&
+                       $newest <= $params->{'skew-new'} &&
+                       $oldest <= $params->{'skew-old'});
+
+       my $msg;
+       if ($skew_ok) {
+               $exitcode = $OK;
+               $msg = "$o_sync mirror(s) not in sync (from oldest to newest), but still within acceptable skew: ";
+       } else {
+               $exitcode = $CRITICAL;
+               $msg = "$o_sync mirror(s) not in sync (from oldest to newest): ";
+       };
+       push @exitstatus, $msg . join(", ", @not_most_recent);
 } else {
-       print "All mirrors unique\n" if $params->{'verbose'};
+       print "All mirrors on same sync timestamp\n" if $params->{'verbose'};
 }
 
 if ($exitcode == $CRITICAL) {
-       print "CRITICAL: " . join(',',@exitstatus) . "\n";
+       print "CRITICAL: " . join(', ',@exitstatus) . "\n";
 } elsif ($exitcode == $OK) {
-       print "OK: all mirrors up2date\n";
+       if (scalar @exitstatus > 0) {
+               print "OK: " . join(', ',@exitstatus) . "\n";
+       } else {
+               print "OK: all mirrors up2date\n";
+       }
 } else {
-       print join(',',@exitstatus) . "\n";
+       print "UNKNOWN: ", join(', ',@exitstatus) . "\n";
 }
 
 foreach my $mirror (keys(%{$status})) {