#!/usr/bin/perl 
#
# BACKGROUND
# This silly plugin checks for errors from NetBackup.
#
# OPERATION
# Run the script.  Or configure it to work in Netsaint.  There are no real
# options yet.  Just make sure the path to "bperror" is correct.  :)
#
# CONFIGURATION
# Set the path for "bperror".  Erm.
#
# ISSUES
# Must be run as root, setuid root, sudo'd up, or something.  Bleh.
#
# TODO
# Allow the user to specify options from the command line, such as how many
# hours to backtrack and what minimum loglevel to check against.
#
# AUTHOR
# Nicholas Tang <ntang@mail.communityconnect.com>

use strict;

my ($minloglevel) = "ERROR";
my ($hoursago) = "1";
#######################################################
# SET THIS PATH CORRECTLY OR YOUR LIFE IS FORFEIT
#######################################################
my $BPERROR = "/opt/openv/netbackup/bin/admincmd/bperror -s $minloglevel+ -hoursago $hoursago";
#######################################################

#######################################################
# Please don't change these.
#######################################################
use constant OK		=> 0;
use constant WARNING	=> 1;
use constant CRITICAL	=> 2;
use constant UNKNOWN	=> 3;
use constant VERSION	=> 0.3;
#######################################################

use vars qw($status %severities %types);

$status = OK;

%severities =	(
		2	=> 'debug',
		4	=> 'info',
		8	=> 'warning',
		16	=> 'error',
		32	=> 'critical'
		); 

%types =  	(
		'unknown'	=> 1,
		'general'	=> 2,
		'backup'	=> 4,
		'archive'	=> 8,
		'retrieve'	=> 16,
		'security'	=> 32, 
		'backstat'	=> 64,
		'mediadev'	=> 128
		);

open IN,"$BPERROR|" || die "Something has gone terribly, terribly wrong with $BPERROR\n";

my $warncount = 0;
my $critcount = 0;

my @errors;
my ($err_type,$sev_lvl);

while (<IN>) {
  chomp($_);
  my (undef,undef,$type,$severity,$server,undef,undef,undef,$client,$process,@errormsg) = split(/ /,$_);
  $err_type = gettype($type);
  $sev_lvl = exists($severities{$severity})?$severities{$severity}:"Unknown";
  my $sep = "/";
  if ( $client eq "*NULL*" ) { $client = ""; $sep = ""; }
  if ( $process eq "*NULL*" ) { $process = ""; $sep = ""; }
  if ( $severity >= 32 ) {
    $critcount++;
  } elsif ( $severity >= 8 ) {
    $warncount++;
  }
  push @errors,"$client$sep$process has $sev_lvl-level $err_type error: @errormsg. ";
}

close IN;

if (defined(@errors)) {
  if ($critcount) { $status = CRITICAL; }
  elsif ($warncount) { $status = WARNING; }
  else { $status = UNKNOWN; }
  print "NETBACKUP ERRORS: (" . ( $critcount + $warncount ) . " total) ";
  my $counta = 0;
  foreach my $errorline (@errors) {
    $counta++;
    print "$counta.) $errorline ";
  }
  print "\n";
} else {
  print "No Netbackup errors found.\n";
}

exit($status);

sub gettype {
  my ($typeval) = @_;
  my ($typename) = "";
  my (@typenames,$key,$typecat,@typecats);
  foreach $key ( sort { $types{$b} <=> $types{$a} } keys %types) {
    push @typecats,$key;
  }
  foreach $typecat (@typecats) {
    if ( $typeval >= $types{$typecat} ) { 
      $typeval = $typeval - $types{$typecat};
      push @typenames,$typecat;
    }
  }
  $typename = join("/",@typenames);
  return($typename);
}
