#!/usr/bin/perl

############################################################################
# check_tsm - check Tivoli Storage Manager for several things, see help for
# more information
#
#
# License Information:
# 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.
#
# To get a copy of the GNU General Public License, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#
############################################################################


use strict;
use TSM;
use Getopt::Long;
use lib "/usr/local/nagios/libexec";
use utils qw(%ERRORS);

my $version="20100927";
my $tsm;
my $logstatus;
my $dbstatus;
my $warning;
my $critical;
my $help;
my $usage;
my $log_utilized;
my $db_utilized;
my $user;
my $pass;
my $type;
my $scratch_count=0;
my $scratch;
my $libr;
my $libr_name;
my $lib_status;
my $path_status;
my $path;
my $source;
my $destination;
my $scratch_used;
my $scratch_max;
my $scratch_count=0;
my $scratch_diff;
my $stgpool;


GetOptions(
   "h"   => \$help,				"help"				=> \$help,
   "w:i" => \$warning,			"warning:i"			=> \$warning,
   "t:s" => \$type,				"type:s"				=> \$type,
   "u:s" => \$user,				"user:s"				=> \$user,
   "p:s" => \$pass,				"pass:s"				=> \$pass,
   "c:i" => \$critical,			"critical:i"		=> \$critical,
   "a:s" => \$path,				"path:s"				=> \$path,
   "s:s" => \$source,			"source:s"			=> \$source,
   "d:s" => \$destination,		"destination:s"	=> \$destination,
   "r:i" => \$scratch_max,		"max_scratch:i"	=> \$scratch_max,
   "m:i" => \$scratch_used,	"used_scratch:i"	=> \$scratch_used,
   "g:s" => \$stgpool,			"stgpool:s"			=> \$stgpool,
   "l:s" => \$libr_name,		"libr:s"				=> \$libr_name);

if ($type =~ /log/){
   &check_log();
}
elsif($type =~ /db/){
   &check_db();
}
elsif($type =~ /max_scratch/){
   &check_max_scratch();
}
elsif($type =~ /scratch/){
   &check_scratch();
}
elsif($type =~ /path/){
   &check_path();
}
else{
   &print_help();
}


sub check_db{
   if (defined $warning && defined $critical){
      $tsm=TSM->new(id => $user, pa => $pass);

      $dbstatus=$tsm->select_single("* from db");
      $db_utilized=$dbstatus->{PCT_UTILIZED};

      if ($db_utilized >= $critical){
         print "Critical: Tivoli DB at $db_utilized\%|PCT_UTILIZED=$db_utilized;$warning;$critical";
         exit $ERRORS{'CRITICAL'};
      }
      elsif ($db_utilized >= $warning){
         print "Warning: Tivoli DB at $db_utilized\%|PCT_UTILIZED=$db_utilized;$warning;$critical;";
         exit $ERRORS{'WARNING'};
      }
      elsif ($db_utilized < $warning){
         print "OK: Tivoli DB at $db_utilized\%|PCT_UTILIZED=$db_utilized;$warning;$critical;";
         exit $ERRORS{'OK'};
      }
      else{
         print"UNKNOWN: something wrong";
         exit $ERRORS{'UNKNOWN'};
      }
   }
}

sub check_log{
   if (defined $warning && defined $critical){
      $tsm=TSM->new(id => $user, pa => $pass);

      $logstatus=$tsm->select_single("* from log");
      $log_utilized=$logstatus->{PCT_UTILIZED};

      if ($log_utilized >= $critical){
         print "Critical: Tivoli Log at $log_utilized\%|PCT_UTILIZED=$log_utilized;$warning;$critical";
         exit $ERRORS{'CRITICAL'};
      }
      elsif ($log_utilized >= $warning){
         print "Warning: Tivoli Log at $log_utilized\%|PCT_UTILIZED=$log_utilized;$warning;$critical";
         exit $ERRORS{'WARNING'};
      }
      elsif ($log_utilized < $warning){
         print "OK: Tivoli Log at $log_utilized\%|PCT_UTILIZED=$log_utilized;$warning;$critical";
         exit $ERRORS{'OK'};
      }
      else{
         print "UNKNOWN: something wrong";
         exit $ERRORS{'UNKNOWN'};
      }
   }
}

sub check_scratch{
   if (defined $warning && defined $critical){
      $tsm=TSM->new(id => $user, pa => $pass);

      $scratch=$tsm->select("* from libvolumes where LIBRARY_NAME='$libr_name'");
#      	or die (print"UNKNOWN: something wrong"; $ERRORS{'UNKNOWN'});

      foreach my $element (@$scratch){
         if ($element->{STATUS} =~ /Scratch/){
            $scratch_count ++;
         }
      }

      if ($scratch_count <= $critical){
         print "Scratch Tapes in $libr_name left: $scratch_count|SCRATCH=$scratch_count;$warning;$critical";
         exit $ERRORS{'CRITICAL'};
      }
      elsif ($scratch_count <= $warning){
         print "Scratch Tapes in $libr_name left: $scratch_count|SCRATCH=$scratch_count;$warning;$critical";
         exit $ERRORS{'WARNING'};
      }
      elsif ($scratch_count > $warning){
         print "Scratch Tapes in $libr_name left: $scratch_count|SCRATCH=$scratch_count;$warning;$critical";
         exit $ERRORS{'OK'};
      }
      else{
         print "UNKNOWN: something wrong";
         exit $ERRORS{'UNKNOWN'};
      }
   }
}

sub check_max_scratch{
   if (defined $warning && defined $critical && defined $stgpool){
      $tsm=TSM->new(id => $user, pa => $pass);

      $scratch_count=$tsm->select_single("* from stgpools where stgpool_name='$stgpool'");
      $scratch_max=$scratch_count->{MAXSCRATCH};
      $scratch_used=$scratch_count->{NUMSCRATCHUSED};
		$scratch_diff=($scratch_max-$scratch_used);

      if ($scratch_diff <= $critical){
         print "Difference between MaxScratch and ScratchUsed at $stgpool is to low: $scratch_diff|SCRATCH_DIFF=$scratch_diff;$warning;$critical";
         exit $ERRORS{'CRITICAL'};
      }
      elsif ($scratch_diff <= $warning){
         print "Difference between MaxScratch and ScratchUsed at $stgpool is to low: $scratch_diff|SCRATCH_DIFF=$scratch_diff;$warning;$critical";
         exit $ERRORS{'WARNING'};
      }
      elsif ($scratch_diff > $warning){
			print "Difference between MaxScratch and ScratchUsed at $stgpool is: $scratch_diff|SCRATCH_DIFF=$scratch_diff;$warning;$critical";
			exit $ERRORS{'OK'};
		}
		else{
			print "UNKNOWN";
         exit $ERRORS{'UNKNOWN'};
      }
   }
}

sub check_path{
   if(defined $source && defined $destination){
      $tsm=TSM->new(id => $user, pa => $pass);

      $path=$tsm->select_single("* from paths where source_name='$source' and destination_name='$destination'");
      $path_status=$path->{ONLINE};

      if ($path_status = "YES"){
         print "path $source -> $destination online: ".$path_status;
         exit $ERRORS{'OK'};
      }
      elsif($path_status = "NO"){
         print "path $source -> $destination online: ".$path_status;
         exit $ERRORS{'CRITICAL'};
      }
      else{
         print"UNKNOWN: something wrong";
         exit $ERRORS{'UNKNOWN'};
      }
   }
}

sub print_help(){
   print "\n\nVersion: $version\n";
   print "Autor: Daniel Bierstedt [d.bierstedt\@crh-group.com]\n\n";
   print "This plugin checks several values from Tivoli Storage Manager\n";
   print "At this point of time available:\n";
   print "\tlog, db, scratch, path, max_scratch\n\n";
   print "You need a user with analyse rights and an installed tsm client\n\n";
   print "Available arguments:\n\n";
   print "\t-h | --help\n";
   print "\t-w | --warning\n";
   print "\t-c | --critical\n";
   print "\t-u | --user\n";
   print "\t-p | --pass\n";
   print "\t-a | --path\n";
   print "\t-l | --libr\n";
   print "\t-g | --stgpool\n";
   print "\t-r | --max_scratch\n";
   print "\t-m | --used_scratch\n";
   print "\t-t | --type (of check to do)\n";
   print "\n\n\n";
   print "Examples:\n\n";
   print "To query Log utilisation:\n";
   print "check_tsm -t log -w 60 -c 80 -u admin -p admin\n\n";
   print "To query DB utilisation:\n";
   print "check_tsm -t db -w 60 -c 80 -u admin -p admin\n\n";
   print "To check scratch tape count:\n";
   print "check_tsm -t scratch -l LIBRARY -w 20 -c 10 -u admin -p admin\n\n";
   print "To check pathes:\n";
   print "check_tsm -t path -s SOURCE -d DESTINATION -u admin -p admin\n\n";
	print "To check difference between NUMSCRATCHUSED and MAXSCRATCH:\n";
	print "check_tsm -t max_scratch -u admin -p admin -g STGPOOL -w 10 -c 5\n\n";
}

