#!/bin/bash
# Nagios plugin to do a Novell eDirectory obituary check
# Written by Jesse Pretorius, jesse.pretorius@gmail.com
# Version 1.4, 18 July 2011
# Project location: exchange.icinga.org
#
# Changelog:
#   v1.4 : Added specific critical error for when eDirectory is in a defunct state
#        : Added specific unknown error when ndsrepair binary could not be found
#   v1.3 : Fixed bug in unprocessed obituaries performance data, thanks to Tim Stein
#        : Added a specific critical error when ndsrepair is unable to connect to eDirectory
#        : Added a specific unknown error when ndsrepair is already running
#        : Thanks to Magnus Felix for the enhancement suggestions
#   v1.2 : Changed alerting to be based on the age of the oldest obit instead
#        : Changed thresholds to be focused on obit age instead of total obits
#        : Changed perf stats to remove total_obits thresholds as they are now invalid
#        : Set the script to figure out where ndsrepair is located
#   v1.1 : Fixed bug in grep for purgeable_obits
#          Added warning and critical thresholds to perf stats output for total_obits

errorlvl=0
tmpfile=`mktemp`
warning=2
critical=5

### Beginning of functions ###

# If inappropriate parameters are provided, this usage statement is output
usage() {
echo -e "\nNagios plugin to do a Novell eDirectory obituary check"
echo -e "Written by Jesse Pretorius, jesse.pretorius@gmail.com"
echo -e "Version 1.4, 18 July 2011"
echo -e "Project location: exchange.icinga.org"
echo -e "\nUsage:"
echo -e "\t$0 <options>"
echo -e "\nOptions:"
echo -e "\t[-w warning]\tThe number of days old the oldest obit must be to produce a warning state. Default: 2"
echo -e "\t[-c critical]\tThe number of days old the oldest obit must be to produce a critical state. Default: 5"
echo -e "\nSample:"
echo -e "\t$0 -w 5 -c 10\n"
exit 3
}

### End of functions ###

while getopts w:c: OPTIONS
do
  case "$OPTIONS" in
    w ) warning=$OPTARG ;;
    c ) critical=$OPTARG ;;
    * ) usage ;;
  esac
done

if [ "$critical" -le "$warning" ]; then
  echo -e "\nThe critical level must be higher than the warning level!"
  usage
  exit 3
fi

# Run the ndsrepair command and save the output to a temporary file
if [ -e /opt/novell/eDirectory/bin/ndsrepair ]; then
  NDSREPAIR="/opt/novell/eDirectory/bin/ndsrepair"
elif [ -e /usr/bin/ndsrepair ]; then
  NDSREPAIR="/usr/bin/ndsrepair"
else
  NDSREPAIR=`which ndsrepair`
fi
$NDSREPAIR -C -Ad -A > $tmpfile 2>&1
ndsrepairerrorlvl="$?"

# If the command produces an error, return the error
if [ "$ndsrepairerrorlvl" -eq "5" ]; then
  output="CRITICAL: Unable to connect to eDirectory!"
  errorlvl=2
elif [ "$ndsrepairerrorlvl" -eq "8" ]; then
  output="UNKNOWN: The ndsrepair module is already loaded."
  errorlvl=3
elif [ "$ndsrepairerrorlvl" -eq "9" ]; then
  output="CRITICAL: eDirectory is in a DEFUNCT state!"
  errorlvl=2
elif [ "$ndsrepairerrorlvl" -eq "127" ]; then
  output="UNKNOWN: The ndsrepair binary could not be found."
  errorlvl=3
elif [ "$ndsrepairerrorlvl" -gt "0" ]; then
  output="UNKNOWN: Failed to run ndsrepair successfully! `cat $tmpfile`"
  errorlvl=3
else
  # Extract the details from the output in the temporary file
  external_references=`grep "external references" $tmpfile | awk '{print $2}'`
  total_obituaries=`grep "total obituaries" $tmpfile | awk '{print $2}'`
  unprocessed_obituaries=`grep "Unprocessed obits" $tmpfile | awk '{print $1}'`
  purgeable_obits=`grep "Purgeable obits" $tmpfile | awk '{print $4}'`
  ok_to_purge_obits=`grep "OK_To_Purge obits" $tmpfile | awk '{print $1}'`
  notified_obits=`grep "Notified obits" $tmpfile | awk '{print $4}'`

  if [ "$total_obituaries" -gt 0 ]; then
    oldest_obit_date=`grep "Value CTS" $tmpfile | awk '{print $4}' | awk -F"-" '{print $3 $1 $2}' | sort -r -u | tail -n 1`

    # Calculate how old the oldest obit is
    current_date=`date +%Y%m%d`
    current_date_unix=$(date --utc --date "$current_date1" +%s)
    oldest_obit_date_unix=$(date --utc --date "$oldest_obit_date" +%s)
    diff_unix=$((current_date_unix-oldest_obit_date_unix))
    if ((diff_unix < 0)); then abs=-1; else abs=1; fi
    oldest_obit_age=$((diff_unix/86400*abs))

    # Work out whether the oldest_obit_age is above any thresholds and set the output accordingly
    if [ "$oldest_obit_age" -ge "$warning" ]; then
      if [ "$oldest_obit_age" -ge "$critical" ]; then
        output="CRITICAL: The oldest obit is $oldest_obit_age day(s) old!"
        errorlvl=2
      else
        output="WARNING: The oldest obit is $oldest_obit_age day(s) old!"
        errorlvl=1
      fi
    else
      output="OK: The oldest obit is $oldest_obit_age day(s) old."
      errorlvl=0
    fi
  else
    output="OK: There are no obits."
    errorlvl=0
  fi

  # Add the performance data to the output
  output="$output | 'external_references'=$external_references 'total_obituaries'=$total_obituaries 'unprocessed_obituaries'=$unprocessed_obituaries 'purgeable_obits'=$purgeable_obits 'ok_to_purge_obits'=$ok_to_purge_obits 'notified_obits'=$notified_obits"
fi

# Clean up the temp file, output the result and the error level
rm -f $tmpfile
echo $output
exit $errorlvl
