#! /bin/bash
#
# latigid010@yahoo.com
# 01/06/2000
#
# enricm@gmail.com
# 16/04/2012
#
# This Nagios plugin was created to check Oracle status on a remote site through SSH
#

PROGNAME=`basename $0`
PROGPATH=`echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,'`
REVISION="0.1"

. $PROGPATH/utils.sh

if [ $# -le 2 ] ; then
	echo "Wrong Parameter Count!"
	exit
fi

REMOTE_SERVER=$2 && shift 2
if [ -z REMOTE_SERVER ]
then
	echo "No remote server specified!!!"
	exit $STATE_UNKNOWN
fi

# Parametres: Si $3="-U" llavors $4 es el OracleOSUser, si no, no.

if [ "${1}" = "-U" ]
then 
	ORACLE_OSUSER=$2 && shift 2	
else
	ORACLE_OSUSER="oracle"
fi

print_usage() {
  echo "Usage:"
  echo "  $PROGNAME -H <Hostname/IP address> [-U Oracle OS User] --tns <ORACLE_SID>"
  echo "  $PROGNAME -H <Hostname/IP address> [-U Oracle OS User] --db <ORACLE_SID>"
  echo "  $PROGNAME -H <Hostname/IP address> [-U Oracle OS User] --login <ORACLE_SID>"
  echo "  $PROGNAME -H <Hostname/IP address> [-U Oracle OS User] --cache <ORACLE_SID> <CRITICAL> <WARNING>"
  echo "  $PROGNAME -H <Hostname/IP address> [-U Oracle OS User] --tablespace <ORACLE_SID> <TABLESPACE> <CRITICAL> <WARNING>"
  echo "  $PROGNAME --help"
  echo "  $PROGNAME --version"
}

print_help() {
  print_revision $PROGNAME $REVISION
  echo ""
  print_usage
  echo ""
  echo "Check Oracle status"
  echo ""
  echo "--tns SID/IP Address"
  echo "   Check remote TNS server"
  echo "--db SID"
  echo "   Check local database (search /bin/ps for PMON process)"
  echo "--login SID"
  echo "   Attempt a dummy login and alert if not ORA-01017: invalid username/password"
  echo "--cache"
  echo "   Check local database for library and buffer cache hit ratios"
  echo "--tablespace"
  echo "   Check local database for tablespace capacity in ORACLE_SID"
  echo "--help"
  echo "   Print this help screen"
  echo "--version"
  echo "   Print version and license information"
  echo ""
  echo "If the plugin doesn't work, check that the ORACLE_HOME environment"
  echo "variable is set, that ORACLE_HOME/bin is in your PATH, and the"
  echo "tnsnames.ora file is locatable and is properly configured on your Oracle server."
  echo ""
  echo "If you want to use a default Oracle home, add in your oratab file:"
  echo "*:/opt/app/oracle/product/7.3.4:N"
  echo ""
  support
}

case "$1" in
1)
    cmd='--tns'
    if [ "$#" -ne 2 ] ; then 
	echo "Wrong Parameter Count!!!"
	exit
    fi
    ;;
2)
    cmd='--db'
    if [ "$#" -ne 2 ] ; then 
	echo "Wrong Parameter Count!!!"
	exit
    fi
    ;;
*)
    cmd="$1"
    ;;
esac

# Information options
case "$cmd" in
--help)
		print_help
    exit $STATE_OK
    ;;
-h)
		print_help
    exit $STATE_OK
    ;;
--version)
		print_revision $PROGNAME $REVISION
    exit $STATE_OK
    ;;
-V)
		print_revision $PROGNAME $REVISION
    exit $STATE_OK
    ;;
esac

# Hunt down a reasonable ORACLE_HOME
GET_ORACLE_HOME='if [ -z "$ORACLE_HOME" ] ; then
	# Adjust to taste
	for oratab in /var/opt/oracle/oratab /etc/oratab
	do
	[ ! -f $oratab ] && continue
	ORACLE_HOME=`IFS=:
		while read SID ORACLE_HOME junk;
		do
			if [ "$SID" = "$ORACLE_SID" -o "$SID" = "*" ] ; then
				echo $ORACLE_HOME;
				exit;
			fi;
		done <<EOF
$(grep -v ^# $oratab)
EOF`
	[ -n "$ORACLE_HOME" ] && echo $ORACLE_HOME ; break
	echo $ORACLE_HOME
	done
fi'
ORACLE_HOME=`ssh $ORACLE_OSUSER@$REMOTE_SERVER -x "ORACLE_SID=${2} ; ${GET_ORACLE_HOME}"`

if [ "$cmd" != "--db" ]; then
	if [ -z "$ORACLE_HOME" -o ! `ssh $ORACLE_OSUSER@$REMOTE_SERVER -x "ls -d ${ORACLE_HOME}"` ] ; then
		echo "Cannot determine ORACLE_HOME for sid $2"
		exit $STATE_UNKNOWN
	fi
fi

case "$cmd" in
--tns)
    tnschk=`ssh $ORACLE_OSUSER@$REMOTE_SERVER -x "ORACLE_HOME=${ORACLE_HOME};PATH=$PATH:$ORACLE_HOME/bin;LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib;export ORACLE_HOME PATH LD_LIBRARY_PATH; tnsping $2"`
    tnschk2=` echo  $tnschk | grep -c OK`
    if [ ${tnschk2} -eq 1 ] ; then 
	tnschk3=` echo $tnschk | sed -e 's/.*(//' -e 's/).*//'`
	echo "OK - reply time ${tnschk3} from $2"
	exit $STATE_OK
    else
	echo "No TNS Listener on $2"
	exit $STATE_CRITICAL
    fi
    ;;
--db)
    pmonchk=`ssh $ORACLE_OSUSER@$REMOTE_SERVER -x "ps -ef | grep -v grep | grep -c ora_pmon_${2}"`
    if [ ${pmonchk} -ge 1 ] ; then
	echo "${2} OK - ${pmonchk} PMON process(es) running"
	exit $STATE_OK
    else
	echo "${2} Database is DOWN"
	exit $STATE_CRITICAL
    fi
    ;;
--login)
    loginchk=`ssh $ORACLE_OSUSER@$REMOTE_SERVER -x "ORACLE_HOME=${ORACLE_HOME};PATH=$PATH:$ORACLE_HOME/bin;LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib;export ORACLE_HOME PATH LD_LIBRARY_PATH;sqlplus dummy/user@$2 < /dev/null"`
    loginchk2=` echo  $loginchk | grep -c ORA-01017`
    if [ ${loginchk2} -eq 1 ] ; then 
	echo "OK - dummy login connected"
	exit $STATE_OK
    else
	loginchk3=` echo "$loginchk" | grep "ORA-" | head -1`
	echo "CRITICAL - $loginchk3"
	exit $STATE_CRITICAL
    fi
    ;;
--cache)
    if [ "$#" -ne 4 ] ; then 
	echo "Wrong Parameter Count!!!"
	exit
    fi
ORACLE_SID=${2}

    if [ ${3} -gt ${4} ] ; then
	echo "UNKNOWN - Warning level is less than Critical"
	exit $STATE_UNKNOWN
    fi

    connect_to_server(){
	ssh $ORACLE_OSUSER@$REMOTE_SERVER -x "ORACLE_HOME=${ORACLE_HOME};PATH=$PATH:$ORACLE_HOME/bin;LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib;ORACLE_SID=${ORACLE_SID} ;export ORACLE_HOME ORACLE_SID PATH LD_LIBRARY_PATH;$GET_RESULT"
	exit
}

    GET_RESULT="sqlplus -s / as sysdba <<EOF
set pagesize 0
set numf '9999999.99'
select (1-(pr.value/(dbg.value+cg.value)))*100
from v\\\$sysstat pr, v\\\$sysstat dbg, v\\\$sysstat cg
where pr.name='physical reads'
and dbg.name='db block gets'
and cg.name='consistent gets'
/
EOF"
    result=`connect_to_server`;

    if [ -n "`echo $result | grep ORA-`" ] ; then
      error=` echo "$result" | grep "ORA-" | head -1`
      echo "CRITICAL - $error"
      exit $STATE_CRITICAL
    fi

    buf_hr=`echo "$result" | awk '/^[0-9\. \t]+$/ {print int($1)}'` 
    buf_hrx=`echo "$result" | awk '/^[0-9\. \t]+$/ {print $1}'` 
    GET_RESULT="sqlplus -s / as sysdba << EOF
set pagesize 0
set numf '9999999.99'
select sum(lc.pins)/(sum(lc.pins)+sum(lc.reloads))*100
from v\\\$librarycache lc;
EOF"
	
    result=`connect_to_server`;

    if [ -n "`echo $result | grep ORA-`" ] ; then
      error=` echo "$result" | grep "ORA-" | head -1`
      echo "CRITICAL - $error"
      exit $STATE_CRITICAL
    fi

    lib_hr=`echo "$result" | awk '/^[0-9\. \t]+$/ {print int($1)}'`
    lib_hrx=`echo "$result" | awk '/^[0-9\. \t]+$/ {print $1}'`

    if [ $buf_hr -le ${3} -o $lib_hr -le ${3} ] ; then
  	echo "${2} CRITICAL - Cache Hit Rates: $lib_hrx% Lib -- $buf_hrx% Buff|lib=$lib_hrx%;${4};${3};0;100 buffer=$buf_hrx%;${4};${3};0;100"
	exit $STATE_CRITICAL
    fi
    if [ $buf_hr -le ${4} -o $lib_hr -le ${4} ] ; then
  	echo "${2} WARNING  - Cache Hit Rates: $lib_hrx% Lib -- $buf_hrx% Buff|lib=$lib_hrx%;${4};${3};0;100 buffer=$buf_hrx%;${4};${3};0;100"
	exit $STATE_WARNING
    fi
    echo "${2} OK - Cache Hit Rates: $lib_hrx% Lib -- $buf_hrx% Buff|lib=$lib_hrx%;${4};${3};0;100 buffer=$buf_hrx%;${4};${3};0;100"

    exit $STATE_OK
    ;;
--tablespace)
    if [ "$#" -ne 5 ] ; then 
	echo "Wrong Parameter Count!!!"
	exit
    fi
    if [ ${4} -lt ${5} ] ; then
	echo "UNKNOWN - Warning level is more than Critical"
	exit $STATE_UNKNOWN
    fi

    ORACLE_SID=$2

    connect_to_server(){
        ssh $ORACLE_OSUSER@$REMOTE_SERVER -x " ORACLE_HOME=${ORACLE_HOME};PATH=$PATH:$ORACLE_HOME/bin;LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib;ORACLE_SID=${ORACLE_SID} ;export ORACLE_HOME ORACLE_SID PATH LD_LIBRARY_PATH;$GET_RESULT"
        exit
}

    GET_RESULT="sqlplus -s / as sysdba << EOF
set pagesize 0
set numf '9999999.99'
select NVL(b.free,0.0),a.total,100 - trunc(NVL(b.free,0.0)/a.total * 1000) / 10 prc
from (
select tablespace_name,sum(bytes)/1024/1024 total
from dba_data_files group by tablespace_name) A
LEFT OUTER JOIN
( select tablespace_name,sum(bytes)/1024/1024 free
from dba_free_space group by tablespace_name) B
ON a.tablespace_name=b.tablespace_name WHERE a.tablespace_name='${3}';
EOF"

    result=`connect_to_server`;

    if [ -n "`echo $result | grep ORA-`" ] ; then
      error=` echo "$result" | grep "ORA-" | head -1`
      echo "CRITICAL - $error"
      exit $STATE_CRITICAL
    fi

    ts_free=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print int($1)}'` 
    ts_total=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print int($2)}'` 
    ts_pct=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print int($3)}'` 
    ts_pctx=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print $3}'` 
    if [ "$ts_free" -eq 0 -a "$ts_total" -eq 0 -a "$ts_pct" -eq 0 ] ; then
        echo "No data returned by Oracle - tablespace $5 not found?"
        exit $STATE_UNKNOWN
    fi
    if [ "$ts_pct" -ge ${4} ] ; then
  	echo "${2} : ${3} CRITICAL - $ts_pctx% used [ $ts_free / $ts_total MB available ]|${3}=$ts_pctx%;${5};${4};0;100"
	exit $STATE_CRITICAL
    fi
    if [ "$ts_pct" -ge ${5} ] ; then
  	echo "${2} : ${3} WARNING  - $ts_pctx% used [ $ts_free / $ts_total MB available ]|${3}=$ts_pctx%;${5};${4};0;100"
	exit $STATE_WARNING
    fi
    echo "${2} : ${3} OK - $ts_pctx% used [ $ts_free / $ts_total MB available ]|${3}=$ts_pctx%;${5};${4};0;100"
    exit $STATE_OK
    ;;
*)
    print_usage
		exit $STATE_UNKNOWN
esac
