#!/usr/bin/perl -w
############################ check_nbu_replication ##############
# Version : 0.0.2
# Date :  Apr 6 2014
# Author  : autolycus
# Site:   
# To list and alarm on the number of queued replications
#################################################################

use strict;
use Getopt::Long;
use Net::SSH::Perl;
use Math::Round;
use File::HomeDir;
use lib '/usr/lib64/nagios/plugins';
use lib "/usr/local/nagios/libexec";
use utils qw(%ERRORS $TIMEOUT);

#my $homedir =		File::HomeDir->my_home;
my $homedir =		glob("~nagios/");
my $version =		"Version 0.0.2 (alpha)";	#current version number
my $o_host =    	undef;		# hostname to run commands against
my $o_user = 		undef;		# user-name for ssh
my $o_pass = 		"";		# password for ssh user (if not key-based)
my $o_port =		undef;		# For an alternative SSH port
my $o_warn =    	undef;		# warning limit
my $o_crit =		undef;		# critical limit
my $command =		undef;		# Command to run on remote host
my $command2 = 		undef;
my $incmplt =		undef;		# Holder for list of incomplete backups
my @replist =		();		# list of replication jobs with backupids
my @backupids = 	();		# list of incomplete replication backupids
my $totalkb =		0;		# totalk backup size
my $totalgb = 		0;		# total estimated GB to be replicated
my $numofbackups =	0;		# number of backups pending replication
my @keyfile =		(glob("~nagios/.ssh/id_rsa")); #keyfile location of current user
my $o_timeout =		10;
my $exit_code = 	3;		# exit code of this script
my $exit_word =		"Unknown";		# exit word based on number of pending jobs
my $exit_message =	undef;		# assembled exit message printed to command line
my $o_type =		undef;
my $output =		undef;		# output holder of ssh command
my $error =		undef;		# error code holder of ssh command
my $rd_exit_code =	undef;		#holder of exit codes from ssh command
my $o_perf = 		1;
my @incmpltary =	undef;		# incomplete replications array
my $o_help =		undef;		# boolean for help message
my $o_ver =		undef;		# boolean for version message
my $o_verb =		undef;		# boolean for verbosity
my $date = 		time;
my $user =		`/usr/bin/whoami`;
$user =			chomp($user);
my $log =		undef;
my $ssh =		undef;		# Net::SSH::Perl holder

sub check_options {
    Getopt::Long::Configure ("bundling");
    GetOptions(
        'H:s'   => \$o_host,            'hostname:s'    => \$o_host,
        'u:s'   => \$o_user,            'user:s'        => \$o_user,
        'p:s'   => \$o_pass,  		'password:s'  	=> \$o_pass,
	'P:s'	=> \$o_port,		'port:s'	=> \$o_port,
        'c:i'   => \$o_crit,            'critical:i'    => \$o_crit,
        'w:i'   => \$o_warn,            'warn:i'        => \$o_warn,
	'h'	=> \$o_help,		'help'		=> \$o_help,
	'V'	=> \$o_ver,		'version'	=> \$o_ver,
	'v'	=> \$o_verb,		'verbose'	=> \$o_verb,
	'vv'	=> \$o_verb,		'vvv'		=> \$o_verb,
    );
}

sub help_message {
	print 'This plugin uses SSH to check a Linux or UNIX based Symantec NetBackup server for pending AIR replications.

Usage:
 check_netbackup_AIR -H|--hostname <host> -u|--user <username> [-p|--password <password>]
	[-P|--port <SSH_Port>] -w|--warn <warning_threshold> -c|--critical <critical_threshold>
	[-h|--help] [-V|--version]

Options:
 -h, --help
    OPTIONAL: Print detailed help screen
 -V, --version
    OPTIONAL: Print version information
 -H, --hostname ADDRESS
    Host name or IP Address of Linux or Unix server running NetBackup
 -u, --user STRING
    Name of user to log into HOSTNAME as via SSH.
 -w, --warn INTEGER
    The number of queued images starting at which the service is considered
    to be in a warning state.
 -c, --critical INTEGER
    The number of queued images starting at which the service is considered
    to be in a critical state.
 -p, --password STRING
    OPTIONAL: If not using public key authentication this option provides
    the password for the user on the remote system.  Note: If the remote
    system is an appliance, password based authentication is not supported.
 -P, --port INTEGER
    OPTIONAL: If not using port 22 for SSH connections to remote host, use
    this option to specify a non-standard port.

 This script will attempt to SSH to the host specified with -H as the
 current user.  It will, by default, look in ~/.ssh/id_rsa for a key to
 use for authentication.  If you do not have key-based authentication
 configured, use the -p option to specify a password.  The -P option
 is to specify a non-standard SSH port (such as for obfuscation), if a
 value is not provided, the default of 22 will be used. The -H, -u -w
 and -c options must be provided or the script will not execute.

Example:
 $ check_netbackup_AIR -H localhost -u root -w 100 -c 500
 SERVICE STATUS: Warning
 389 waiting for replication.
 4475 GB estimated replication size.

';
	exit (3);
}

sub validate_options {
	print $log "validating options\n";
	if ($o_help) {
                help_message();
        }
        if ($o_ver) {
                print "$version\n";
                exit (0);
        }
	if (!($o_host && $o_user && $o_crit && $o_warn)) {
		print $log "options problem";
		my @badopts = ();
		my $badlist = "";
		my $optionpl = "OPTION";
		if (!$o_host) { print $log " with HOSTNAME\n"; push @badopts, "HOSTNAME\n"; }
		if (!$o_user) { print $log " with USERNAME\n";push @badopts, "USERNAME\n"; }
		if (!$o_crit) { print $log " with CRITICAL THRESHOLD\n";push @badopts, "CRITICAL THRESHOLD\n"; }
		if (!$o_warn) { print $log " with WARNING THRESHOLD\n";push @badopts, "WARNING THRESHOLD\n"; }
		my $i = 0;
		foreach (@badopts) {
			chomp($_);
			if ($i > 0) {
				$optionpl = "OPTIONS";
				$badlist .= ", ";
			}
			$badlist .= $_;
			$i++;
		}
		print "$optionpl NOT FOUND: $badlist\n";
		help_message();
	}
}

check_options();
if ($o_verb) { open $log, ">", "/tmp/logfile$date.log" || warn "Can't open log: $!\n"; } else { open $log, ">", "/dev/null"; }
print $log "$user :: $homedir\n";
validate_options();
$o_port = 22 unless $o_port;
$ENV{HOME} = $homedir || print $log "cannot set \$HOME: $!\n";       # force the home dir to the nagios user's home folder

print $log "completed option processing\n";
if ($o_verb) {
	select $log;
	open STDERR, '>>', "/tmp/logfile$date.log" || print $log "cannot open STDERR: $!\n";
	$ssh = Net::SSH::Perl->new($o_host, identity_files=>\@keyfile, debug => 1) || print $log "SSH ERROR: $!\n";
} else {
	$ssh = Net::SSH::Perl->new($o_host, identity_files=>\@keyfile);
}
print $log "built ssh connection\n";
if (length $o_pass > 0) {
	print $log "with password\n";
	$ssh->login($o_user,$o_pass) || print $log "SSH ERROR: $!\n";
	print $log "authenticated\n";
} else {
	print $log "wihtout password\n";
	$ssh->login($o_user) || print $log "SSH ERROR: $!\n";
	print $log "authenticated\n";
}
print $log "authentication completed\n";
$command = "/usr/openv/netbackup/bin/admincmd/nbstlutil stlilist -U -image_incomplete -copy_type 3";
( $output, $error, $rd_exit_code ) = $ssh->cmd( $command );
print $log "ssh output: $output\nssh error: $error\nssh exit code: $rd_exit_code\n";
select STDOUT;
$incmplt = $output;
my $i = 0;
$incmplt = "" unless $incmplt;
@incmpltary = split(/^/, $incmplt);
$numofbackups = @incmpltary;
foreach (@incmpltary) {
	my $x = $i - 1;
	if (/REPLICATE/) {
		push @replist, $incmpltary[$x];
		my $hold = (split ' ',$incmpltary[$x])[1];
		push @backupids, $hold;
	}
	$i++;
}
print $log "found $i matches for REPLICATE\n";
foreach (@backupids) {
	$command2 = "/usr/openv/netbackup/bin/admincmd/bpimagelist -l -backupid $_";
	($output, $error, $rd_exit_code) = $ssh->cmd( $command2 );
	my @outputs = split /^/,$output;
	foreach (@outputs) {
		my $hold = (split ' ', $_)[18];
		$hold = 0 unless $hold;
		$totalkb += $hold;
	}
}
if ($numofbackups >= $o_warn) {
	if ($numofbackups >= $o_crit) {
		$exit_code = 2;
		$exit_word = "Critical";
	} else {
		$exit_code = 1;
		$exit_word = "Warning";
	}
} else {
	$exit_code = 0;
	$exit_word = "OK";
}
$totalgb = nearest(1, $totalkb/1024/1024);
$exit_word .= " | pending_replications=$numofbackups, size_to_replicate=$totalgb";
if ($exit_code == 3) {
	$exit_message = "The script could not determine the current status.";
} else {
	$exit_message = "$numofbackups waiting for replication.\n$totalgb GB estimated replication size.\n";
}
print "SERVICE STATUS: $exit_word\n$exit_message\n";
exit ($exit_code);

