#!/bin/bash

# The higher this number, the more debug output you get. 0 is 100% silent. Max=3.
# You can override this on the command line with "--DEBUGLEVEL <lvl>" as the FIRST "--" option.
DEBUGLEVEL=0

function print_help {
	echo '
This program is designed to be run from Nagios as a command. Example:
define command {
	command_name                    notify-host-rt
	command_line                    /usr/lib/nagios/plugins/notify_rt -m rt_host --RTUSER username --RTPASSWD password \
	--RTSERVER http://rt.example.com/ --RTQUEUE queue_name --HOSTNAME $HOSTNAME$ --HOSTSTATE $HOSTSTATE$ \
	--HOSTPROBLEMID $HOSTPROBLEMID$ --LASTHOSTPROBLEMID $LASTHOSTPROBLEMID$ --HOSTOUTPUT="$HOSTOUTPUT$"
	register                        1
}
define command {
	command_name                    notify-service-rt
	command_line                    /usr/lib/nagios/plugins/notify_rt -m rt_service --RTUSER username --RTPASSWD password \
	--RTSERVER http://rt.example.com/ --RTQUEUE queue_name --SERVICEPROBLEMID $SERVICEPROBLEMID$ --LASTSERVICEPROBLEMID $LASTSERVICEPROBLEMID$ \
	--HOSTNAME $HOSTNAME$ --SERVICEDESC "$SERVICEDESC$" --SERVICESTATE $SERVICESTATE$ --SERVICEOUTPUT="$SERVICEOUTPUT$"
	register                        1
}

-m sets the script to look for either host variables (rt_host) or service variables (rt_service).
Each "--" option sets an environment variable of that name which are used in the script.

Other Options:
--DEBUGLEVEL <1,2,3>       Outputs more information to stderr the higher the number is. Good for command line testing.
                           NOTE: This must be the first "--" option or you will miss some option parsing in the output.
--NAGIOSHOST <string>      Sets the nagioshost in [nagioshost:problemid] in the ticket subject. Defaults to the output of the "hostname" command.
'
}

if [[ -z "$@" ]]; then
	print_help
	exit 3
fi

# Check for programs we need
which rt > /dev/null || { echo "Can't find rt command line client"; exit 1; }
which grep > /dev/null || { echo "Can't find grep"; exit 1; } 
which sed > /dev/null || { echo "Can't find sed"; exit 1; }
which awk > /dev/null || { echo "Can't find awk"; exit 1; }

# Static Variables
X_OK=0
X_WARN=1
X_CRIT=2
X_UNKN=3

# Functions

function help_rt {
	echo "Usage: $0 -m [rt_host|rt_service] --RTUSER <username> --RTPASSWD <password> --RTSERVER <server url> --RTQUEUE <queue>" 
}

function debug {
# Takes two arguments:
#<Debuglevel>
#<Message>

  if [ $DEBUGLEVEL -ge $1 ]; then
    case "$1" in
    1|2|3) # Debug levels that output something
      echo "$2" 1>&2
      ;;
    0) # Debug level thats 100% Silent
      ;;
    *) # Other, invalid debug levels
      echo "WARNING: Invalid Debug Level $1! I'm outputting everything to be safe." 1>&2
      echo $2 1>&2
      ;;
    esac
  fi
}

function rt_config {
	# Make sure RT login variables are set
	if [ -z "$RTUSER" ] || [ -z "$RTPASSWD" ] || [ -z "$RTSERVER" ] || [ -z "$RTQUEUE" ]; then
		help_rt
		exit $X_UNKN
	fi

	# Export RT login vars
	export RTUSER
	export RTPASSWD
	export RTSERVER
}

function send_rt_service {
	# Run RT config setup function
	rt_config
	# Make sure Nagios host problem ID's were set.
	if 	[[ -z "$SERVICEPROBLEMID" ]] || \
			[[ -z "$LASTSERVICEPROBLEMID" ]] || \
			[[ -z "$HOSTNAME" ]] || \
			[[ -z "$SERVICEDESC" ]] || \
			[[ -z "$SERVICESTATE" ]] \
			;then
		echo "SERVICEPROBLEMID, LASTSERVICEPROBLEMID, HOSTNAME, SERVICEDESC and/or SERVICESTATE variables not set"
		exit $X_UNKN
	fi
	
	# See if the SERVICEPROBLEMID is 0. If so, this is a resolution and we are searching for the LASTSERVICEPROBLEMID.
	if [ $SERVICEPROBLEMID -eq 0 ]; then
		NAGIOSPROBLEMID=$LASTSERVICEPROBLEMID
	else
		NAGIOSPROBLEMID=$SERVICEPROBLEMID
	fi
	debug 2 "NAGIOSPROBLEMID=[$NAGIOSPROBLEMID]"
	
	# Search for existing ticket
	TICKETID=$(rt list -i "Subject LIKE '[$NAGIOSHOST:$NAGIOSPROBLEMID]'" | awk -F"/" '{print $2}')
	debug 2 "TICKETID=[$TICKETID]"
	
	# If we found a ticket, and NAGIOSPROBLEMID is 0, we want to comment and resolve the ticket.
	if [ $SERVICEPROBLEMID -eq 0 ] && ! [ -z "$TICKETID" ]; then
		debug 2 "Close ticket ${TICKETID} for Nagios Problem [$NAGIOSHOST:${NAGIOSPROBLEMID}]"
		rt correspond -m "Nagios problem ${NAGIOSPROBLEMID} resolved at $(date)" ${TICKETID}
		rt resolve ${TICKETID}
	fi
		
	# If we didn't find a ticket and the $SERVICEPROBLEMID is greater then 0 we create a new ticket.
	if [ $SERVICEPROBLEMID -gt 0 ] && [ -z "$TICKETID" ]; then
		debug 2 "Create new ticket for Nagios Problem [$NAGIOSHOST:${NAGIOSPROBLEMID}] for service ${SERVICEDESC} on host ${HOSTNAME}"
		rt create -t ticket set queue="${RTQUEUE}" subject="[$NAGIOSHOST:$NAGIOSPROBLEMID] SERVICE $SERVICEDESC on $HOSTNAME is $SERVICESTATE" text="$SERVICEOUTPUT"
	fi
	
	# If we find a ticket for this and the $SERVICEPROBLEMID is *not* 0, then this is a repeat notification
	# and we want to append it to the existing ticket.
	if [ $SERVICEPROBLEMID -gt 0 ] && ! [ -z "$TICKETID" ]; then
		debug 2 "Append ticket ${TICKETID} for Nagios Problem [$NAGIOSHOST:${NAGIOSPROBLEMID}]"
		rt correspond -m "$SERVICEOUTPUT" ${TICKETID}
	fi
}

function send_rt_host {
	# Run RT config setup function
	rt_config
	# Make sure Nagios host problem ID's were set.
	if 	[[ -z "$HOSTPROBLEMID" ]] || \
			[[ -z "$LASTHOSTPROBLEMID" ]] || \
			[[ -z "$HOSTNAME" ]] || \
			[[ -z "$HOSTSTATE" ]] \
			;then
		echo "HOSTPROBLEMID, LASTHOSTPROBLEMID, HOSTNAME, and/or HOSTSTATE variables not set"
		exit $X_UNKN
	fi
	
	# See if the HOSTPROBLEMID is 0. If so, this is a resolution and we are searching for the LASTHOSTPROBLEMID.
	if [ $HOSTPROBLEMID -eq 0 ]; then
		NAGIOSPROBLEMID=$LASTHOSTPROBLEMID
	else
		NAGIOSPROBLEMID=$HOSTPROBLEMID
	fi
	debug 2 "NAGIOSPROBLEMID=[$NAGIOSPROBLEMID]"
	
	# Search for existing ticket
	TICKETID=$(rt list -i "Subject LIKE '[$NAGIOSHOST:$NAGIOSPROBLEMID]'" | awk -F"/" '{print $2}')
	debug 2 "TICKETID=[$TICKETID]"
		 
	# If we found a ticket, and NAGIOSPROBLEMID is 0, we want to comment and resolve the ticket.
	if [ $HOSTPROBLEMID -eq 0 ] && ! [ -z "$TICKETID" ]; then
		debug 2 "Close ticket ${TICKETID} for Nagios Problem [$NAGIOSHOST:${NAGIOSPROBLEMID}]"
		rt correspond -m "Nagios problem ${NAGIOSPROBLEMID} resolved at $(date)" ${TICKETID}
		rt resolve ${TICKETID}
	fi
	
	# If we didn't find a ticket and the $HOSTPROBLEMID is greater then 0 we create a new ticket.
	if [ $HOSTPROBLEMID -gt 0 ] && [ -z "$TICKETID" ]; then
		debug 2 "Create new ticket for Nagios Problem [$NAGIOSHOST:${NAGIOSPROBLEMID}]"
		rt create -t ticket set queue="${RTQUEUE}" subject="[$NAGIOSHOST:$NAGIOSPROBLEMID] Host $HOSTNAME is $HOSTSTATE" text="$HOSTOUTPUT"
	fi
	
	# If we find a ticket for this and the $HOSTPROBLEMID is *not* 0, then this is a repeat notification
	# and we want to append it to the existing ticket.
	if [ $HOSTPROBLEMID -gt 0 ] && ! [ -z "$TICKETID" ]; then
		debug 2 "Append ticket ${TICKETID} for Nagios Problem [$NAGIOSHOST:${NAGIOSPROBLEMID}]"
		rt correspond -m "$HOSTOUTPUT" ${TICKETID}
	fi
}

########################################
# MAIN CODE                            #
########################################

# Get this servers hostname, since $HOSTNAME may be overwritten
# You can override this too, for debuging purposes.
NAGIOSHOST=$(hostname)

# Loop though command line arguments
index=0
for argument in $@; do
	let index=index+1
	if [[ $argument == --* ]]; then
		if [[ $argument == -- ]]; then
			break
		fi
		ARG=${argument#--}
		declare $ARG="$(grep -oP "(?<=$argument).*?(?=--|$)" <<< "${@}" | sed -e 's/^ *//g' -e 's/ *$//g')"
		debug 2 "$ARG=[${!ARG}]"
	fi
done

while getopts ":m:b:h" OPTION;
do
        case $OPTION in
                "m")
                        NOTIFICATION_METHOD="$OPTARG"
                        debug 1 "NOTIFICATION_METHOD=[$NOTIFICATION_METHOD]"
                ;;
                "h") # Print application help
                        print_help
                        exit $X_OK
                ;;
        esac
done

case $NOTIFICATION_METHOD in
	"rt_host") # Create/Append/Resolve Request Tracker Ticket for Host
		send_rt_host
	;;
	"rt_service") # Create/Append/Resolve Request Tracker Ticket for Host
		send_rt_service
	;;
	*|'') # Unknown method
		echo "Unknown Notification Method: $NOTIFICATION_METHOD"
		exit 3
	;;
esac