From 41291a8d0d8d45461d290d073264a38ae6b154bf Mon Sep 17 00:00:00 2001 From: Benjamin Renard Date: Tue, 20 Aug 2013 16:15:39 +0200 Subject: [PATCH] Initial commit --- check_backuppc | 210 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100755 check_backuppc diff --git a/check_backuppc b/check_backuppc new file mode 100755 index 0000000..7f76d80 --- /dev/null +++ b/check_backuppc @@ -0,0 +1,210 @@ +#!/usr/bin/perl +# +# check_backuppc: a Nagios plugin to check the status of BackupPC +# +# Tested against BackupPC 3.2.1 and Nagios 3 +# +# +# +# AUTHORS +# Benjamin Renard +# +# Fork from check_backuppc 1.1.0 write by Seneca Cunningham +# . +# +# COPYRIGHT +# Copyright (C) 2013 Easter-eggs +# +# 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +use strict; +no utf8; + +# Nagios +use lib "/usr/lib/nagios/plugins"; +use utils qw(%ERRORS $TIMEOUT); +use POSIX qw(strftime difftime); +use Getopt::Long; +Getopt::Long::Configure('bundling'); + +# BackupPC +use lib "/usr/share/backuppc/lib"; +use BackupPC::Lib; + +my $version = '1.1.1'; +my $warnDaysOld = 2; +my $critDaysOld = 7; +my $verbose = 0; +my $opt_V = 0; +my $opt_h = 0; +my $goodOpt = 0; +my @ownerOnly; +my @hostsDesired; +my @hostsExcluded; + +# Process options +$goodOpt = GetOptions( + 'v+' => \$verbose, 'verbose+' => \$verbose, + 'c=f' => \$critDaysOld, 'critical=f' => \$critDaysOld, + 'w=f' => \$warnDaysOld, 'warning=f' => \$warnDaysOld, + 'o=s' => \@ownerOnly, 'owner=s' => \@ownerOnly, + 'V' => \$opt_V, 'version' => \$opt_V, + 'h' => \$opt_h, 'help' => \$opt_h, + 'H=s' => \@hostsDesired, 'hostname=s' => \@hostsDesired, + 'x=s' => \@hostsExcluded, 'exclude=s' => \@hostsExcluded); + +@hostsDesired = () if $#hostsDesired < 0; +@hostsExcluded = () if $#hostsExcluded < 0; + +if ($opt_V) +{ + print "check_backuppc - " . $version . "\n"; + exit $ERRORS{'OK'}; +} +if ($opt_h or not $goodOpt) +{ + print "check_backuppc - " . $version . "\n"; + print "A Nagios plugin to check on BackupPC backup status.\n\n"; + print "Options:\n"; + print " --hostname,-H only check the specified host\n"; + print " --exclude,-x do not check the specified host\n"; + print " --owner,-o do only hosts of specified user\n"; + print " --warning,-w days old of last good backup to cause a warning\n"; + print " --critical,-c days old of last good backup to be critical\n"; + print " --verbose,-v increase verbosity\n"; + print " --version,-V display plugin version\n"; + print " --help,-h display this message\n\n"; + exit $ERRORS{'OK'} if $goodOpt; + exit $ERRORS{'UNKNOWN'}; +} +if ($warnDaysOld > $critDaysOld) +{ + print("BACKUPPC UNKNOWN - Warning threshold must be <= critical\n"); + exit $ERRORS{'UNKNOWN'}; +} + +# Connect to BackupPC +my $server; +if (!($server = BackupPC::Lib->new)) +{ + print "BACKUPPC CRITICAL - Couldn't connect to BackupPC\n"; + exit $ERRORS{'CRITICAL'}; +} +my %Conf = $server->Conf(); + +$server->ChildInit(); + +my $err = $server->ServerConnect($Conf{ServerHost}, $Conf{ServerPort}); +if ($err) +{ + print("BACKUPPC UNKNOWN - Can't connect to server ($err)\n"); + exit $ERRORS{'UNKNOWN'}; +} + +my %Status; + +# query the BackupPC server for host status +my $status_raw = $server->ServerMesg('status hosts'); +my $hosts_infos = $server->HostInfoRead(); + +# undump the output... BackupPC uses Data::Dumper +eval $status_raw; + +# check the dumped output +my $hostCount = 0; +my $errorLevel='OK'; + +foreach my $host (@hostsDesired, @hostsExcluded) +{ + if (not grep {/$host/} keys(%Status)) + { + print("BACKUPPC UNKNOWN - Unknown host ($host)\n"); + exit $ERRORS{'UNKNOWN'}; + } +} + +my @problems; + +# host status checks +foreach my $host (sort(keys(%Status))) +{ + next if $host =~ /^ /; + my $owner = $hosts_infos->{$host}->{user}; + next if (@ownerOnly and not grep {/$owner/} @ownerOnly); + my %host_conf = %{$server->ConfigDataRead($host)}; + next if ( $host_conf{BackupsDisable} ); + next if (@hostsDesired and not grep {/$host/} @hostsDesired); + next if (@hostsExcluded and grep {/$host/} @hostsExcluded); + next if ($Status{$host}{'type'} eq 'archive'); + $hostCount++; + # Debug + if ($verbose == 2) + { + print "Host $host state " . $Status{$host}{'state'} . "\n"; + print " with reason: " . $Status{$host}{'reason'} . "\n"; + print " with error: " . $Status{$host}{'error'} . "\n"; + print " with owner: $owner\n\n"; + } + # Check host error + if ($Status{$host}{'error'}) + { + # Check connectivity errors with greater care + if ($Status{$host}{'error'} ne 'ping too slow' && + $Status{$host}{'error'} ne 'no ping response' && + $Status{$host}{'error'} ne 'no ping response' && + $Status{$host}{'error'} ne 'host not found' && + $Status{$host}{'reason'} !~ /Reason_restore_failed/) { + push @problems, "$host error : ".$Status{$host}{'error'}." / ".$Status{$host}{'reason'}; + next; + } + } + # Check last good backup time + my $difftime=difftime(time(), $Status{$host}{'lastGoodBackupTime'}); + my $diffdays=$difftime/(3600 * 24); + $Status{$host}{'lastGoodBackupTime'} = $Status{$host}{'startTime'} if (not $Status{$host}{'lastGoodBackupTime'}); + if ($difftime > ($critDaysOld * 3600 * 24)) + { + push @problems, "$host : last good backup have ".sprintf("%.1f",$diffdays)." days"; + $errorLevel='CRITICAL'; + } + elsif ($difftime > ($warnDaysOld * 3600 * 24)) + { + push @problems, "$host : last good backup have ".sprintf("%.1f",$diffdays)." days"; + $errorLevel='WARNING' if ($errorLevel eq 'OK'); + } +} + +my $problemTxt=""; +if (scalar(@problems) > 0) { + if ($verbose > 0) { + foreach my $pbl (@problems) { + if ($problemTxt ne "") { + $problemTxt.=" , "; + } + else { + $problemTxt=" ( "; + } + $problemTxt.=$pbl; + } + $problemTxt.=" )"; + } + else { + $problemTxt=" (".scalar(@problems)." problems)"; + } +} + +print "BACKUPPC $errorLevel$problemTxt\n"; +exit $ERRORS{$errorLevel};