#!/usr/bin/perl

# /******************************************************************************
# *
# * CHECK_ORACLE_ASM_DISK_GROUPS_B
# *
# * Program: Linux plugin for Nagios
# * License: GPL
# * Modified plugin (v2) by eldespistado.com. Original Plugin: 2013- Victor Ruiz (vruiz@adif.es)
# *
# * Description:
# *
# * This software checks the used space for disk_groups
# * managed by Oracle ASM (Automatic Storage Management)
# * against a threshold provided in command line
# *
# * 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.
# *
# * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
# *
# * $Id: check_oracle_ASM_disk_groups ,v 2 2013/25/07  $
# *
# *****************************************************************************/

use Getopt::Long qw(:config no_ignore_case);
use DBI;
use DBD::Oracle qw(:ora_session_modes);


#my $sid = 'orcl1pre1';
my $sid = '';
#my $ora_home = '';
my $ora_home = '/usr/lib/oracle/11.2/client64';
#my %disk_groups_thresholds = ('FRA',20,'DATA01',20);
my %disk_groups_thresholds = ();
my %nagios_exit_codes = ( 'UNKNOWN', 3, 'OK', 0, 'WARNING', 1, 'CRITICAL', 2 );
my $output_msg = '';
my $status = 'OK';
# MIO
my $output_perf = ' | ';
my $user = '';
my $password = '';
my $user_mode = 'normal';


&usage unless GetOptions ('sid=s' => \$sid, 'ora_home=s' => \$ora_home, 'user=s' => \$user, 'password=s' => \$password,  'user_mode=s' => \$user_mode, 'threshold=s' => \%disk_groups_thresholds);




$dsn = "dbi:Oracle:$sid";
$ENV{ORACLE_SID} = $sid;
$ENV{ORACLE_HOME} = $ora_home;
delete $ENV{TWO_TASK};

# MIO
if ($user_mode eq 'sysdba'){
  $dbh = DBI->connect($dsn, $user, $password, { ora_session_mode => ORA_SYSDBA });
} else {
  $dbh = DBI->connect($dsn, $user, $password);
}

if ( ! defined $dbh ) { print "$DBI::errstr\n"; exit $nagios_exit_codes{'CRITICAL'}; }

$dbh->{RaiseError} = 1;
$sth = $dbh->prepare(qq{select name, free_mb, total_mb from v\$asm_diskgroup}) or die $dbh->errstr;


if ( $sth->execute ) {

	$output_msg .= "USED SPACE: ";
	# Traverse all disk groups in ASM
	while ( @disk_group = $sth->fetchrow_array()) {
		my $used_space = 0;
		my $rounded_used_space = 0;
		chomp @disk_group;
		# If the disk group in ASM has threshold defined in command line let's check it  
		if ( $disk_groups_thresholds{$disk_group[0]} ){
			if ( $disk_group[2] != 0 ) {
				$used_space = (  ($disk_group[2] - $disk_group[1]) / $disk_group[2] ) * 100;
				$rounded_used_space = sprintf("%.2f", $used_space);
			}
			if ( $rounded_used_space > $disk_groups_thresholds{$disk_group[0]} ) {
				$status = 'CRITICAL';
				$output_msg .= "  [<blink><b>$disk_group[0]: $rounded_used_space%<\/b><\/blink>]";

			}else{
				$output_msg .= "[$disk_group[0]: $rounded_used_space%]   ";
			}
                     #MIO
                     $output_perf .= "$disk_group[0]=$rounded_used_space%;;$disk_groups_thresholds{$disk_group[0]} ";
			# Once processed, we drop command line disk group and threshold
			delete($disk_groups_thresholds{$disk_group[0]});
		} # end if
	} # end while
       #$output_msg .= "\n";
 } else {
	$status = 'CRITICAL';
	print $dbh->errstr;
}

# Free DBI resources
# da un error al liberar esto comentado. ***** MIO ****
#$sth->finish();  
$dbh->disconnect();


# Let's check if any disk group remains in command line, not being present in ASM 
if ( scalar keys %disk_groups_thresholds ) {
	$status = 'CRITICAL';
	foreach ( keys(%disk_groups_thresholds) ) {
	$output_msg = "[<blink><b>$_ is not in $sid<\/b><\/blink>] " . $output_msg;	
	}
}

#print $output_msg;
print $output_msg . $output_perf . "\n";
exit $nagios_exit_codes{ $status };


########################## SUBROUTINES #######################

sub usage {
   print "\nUsage: $0 --sid <SID> --ora_home <ORACLE_HOME for SID> --user <USER> --password <PASS> --user_mode <normal|sysdba> --threshold <GROUP_DISK=integer> [[--threshold <GROUP_DISK=integer>] ... ]\n\n";
   print "--sid:		SID name of ASM instance (in tnsnames.ora)\n";
   print "--ora_home:	ORACLE_HOME for SID, to find tnsnames.ora in \$ORACLE_HOME\\network\\admin\n";
   print "--user:		User for connect\n";
   print "--password:	Password for user\n";
   print "--user_mode:	normal: 'normal user', sysdba: 'as sysdba' (default mode = normal, you can use sysdba oracle user for test)\n";
   print "For non sysdba Oracle user (recommended) you need privileges\: GRANT CREATE SESSION to YourUser\; GRANT SELECT ON v_\$asm_diskgroup TO YourUser\;\n";
   print "--threshold:	GROUP_DISK_NAME=percentage threshold for used space (range [0..100])\n";
   exit $nagios_exit_codes{'WARNING'};
}
