#!/bin/bash
#
# 2004.03.19 - Jeff Vier
# This script is released under the GNU Public License.
#
# This plugin wraps the Nagios plugn 'check_http' to do multiple URL checks
# 
# Your check command (in nagios/etc/checkcommands.cfg) should look something like this:
# ---
# define command {
#	command_name                    check_http_many
#	command_line                    $USER1$/check_http_many $ARG1$
#	}
# ---
# The $ARG1$ will be the path to a file of URLs
# You can pile on any normal check_http arguments, too.  AFTER the $ARG1$ only!
# 
#
# Then, of course, add a service definition (typically in nagios/etc/services.cfg):
# ---
# define service {
#	use			generic-service
#	host_name		serverA
#	service_description	Check Many URLs
#	check_command		check_http_many!/path/to/file.txt
#	}
# ---
#
# Then stop/start nagios and you're done.
#
# Usage block:
function usageblock
{
if [ ! -f "$1" ] && [ -n "$1" ] && [ "$1" != "-h" ] && [ "$1" != "--help" ]; then
	echo -e "\nI'm sorry, I couldn't find the file [$1]"
fi
echo "
Usage:
	${0} [/path/url-file.txt] <any check_http args>

Run '${0#_*} --help' for help with check-http arguments.

Notes:
	- Your url-file should be plain text, one url per line (no length limit beside system limitations)
	- If you want to use 'relative' URLs ('/file.html') in your url-file, you must supply a -H <hostname> option
	  (example: ${0} /usr/local/nagios/etc/server1-urls.txt -H server1.blah.com)
	- URLs n your url-file need to either start with \"http://\" or \"/\" or it will fail.
	- You can comment out URLs in your url-file with a # as the *first* character on the line.
	- Processing is halted upon the first bad URL; the return code is based on the result of that check (warn/crit/unknown) and bad URL is displayed."
exit 3
}
# end usage block:

# derives the plugins directory from $0 
NAGIOSPLUGSDIR=${0%/*}
# Assumes check_http is in the same directory as this plugin is
CHECK_HTTP=$NAGIOSPLUGSDIR/check_http
# Exit as 'unknown' state if no check_http is found
if [ ! -f "$CHECK_HTTP" ]; then
	echo "Error: $CHECK_HTTP not found"
	exit 3
fi

# if $1 is null, "-h", "--help", or points to a non-existant file, show usage.
if [ -z "$1" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ] || [ ! -f "$1" ]; then
	usageblock
fi

# OK=0
# WARNING=1
# CRITICAL=2
# UNKNOWN=3

# cycle through the arguments past the first one (first one has to be the file with the URLs)
ARGS=($@)
j=1
while [ $j -lt $# ]; do
	# if --help or -H appears anywhere in the arguments, show usage
	if [ "${ARGS[$j]}" = "--help" ] || [ "${ARGS[$j]}" = "-h" ]; then usageblock; fi
	CHECK_COMMAND="$CHECK_COMMAND ${ARGS[$j]}"
	let j=$j+1
done

# set up done, ready to run the command...
# default result code (result code so far)
RES=$?
if [ $RES -ne 0 ]; then
	# returned text if some failure happened before 
	RET="Something pre-check failed."
else
	# reset URL_COUNT
	URL_COUNT=0
	{
	while read url; do
		# Skip comments
		if [ "${url:0:1}" = "#" ];then continue; fi
		# handle (chop-up) http:// URLs
		if [ "${url:0:7}" = "http://" ]; then
			# Since this is a full URL, strip any -H/--hostname from the arg list
			CHECK_COMMAND=$(echo $CHECK_COMMAND | sed 's/ -H [^[:blank:]]*//g' | sed 's/ --hostname=[^[:blank:]]*//g')
			# Establish the hostname and the length thereof
			HOST=$(echo ${url:7} | awk -F/ '{print $1}')	# Hmm.  vim doesn't like ${var:n} syntax.  It's fine, though. I promise.
			HOSTLEN=$(echo http://$HOST|wc -c)
			# And, finally the rest of the URL is the URI we pass
			URI=${url:${HOSTLEN}}
			# Execute the check:
			RET=$($CHECK_HTTP $NOHOST_CHECK_COMMAND -H $HOST -u ${URI:=/})
			# if result is non-zero, end processing
			if [ $? -ne 0 ]; then
				echo "Line $((URL_COUNT+1)): [$url] - $RET"
				exit $RES
			fi
		# handle https:// URLs
		elif [ "${url:0:8}" = "https://" ]; then
			# No -S or --ssl with https:// URL?  Bad admin!
			if [ -z "$(echo $CHECK_COMMAND | sed 's/.*\(-S\).*/\1/g')" ] && [ -z "$(echo $CHECK_COMMAND | sed 's/.*\(--ssl\).*/\1/g')" ];then
				echo "Line $((URL_COUNT+1)) [${url}]: No -H arg supplied for relative URL checking"
				exit 3
			fi
			# Since this is a full URL, strip any -H/--hostname from the arg list
			CHECK_COMMAND=$(echo $CHECK_COMMAND | sed 's/ -H [^[:blank:]]*//g' | sed 's/ --hostname=[^[:blank:]]*//g')
			# Establish the hostname and the length thereof
			HOST=$(echo ${url:8} | awk -F/ '{print $1}')
			HOSTLEN=$(echo https://$HOST|wc -c)
			# And, finally the rest of the URL is the URI we pass
			URI=${url:${HOSTLEN}}
			# Execute the check:
			RET=$($CHECK_HTTP $NOHOST_CHECK_COMMAND -H $HOST -u ${URI:=/})
			# if result is non-zero, end processing
			if [ $? -ne 0 ]; then
				echo "Line $((URL_COUNT+1)): [$url] - $RET"
				exit $RES
			fi
		# handle relative paths
		elif [ "${url:0:1}" = "/" ];then
			# No -H (or --hostaddress=) with relative paths?  Bad admin!
			if [ -z "$(echo $CHECK_COMMAND | sed 's/.* \(-H [^[:blank:]]*\).*/\1/g')" ] && [ -z "$(echo $CHECK_COMMAND | sed 's/.*\(--hostname=[^[:blank:]]*\).*/\1/g')" ];then
				echo "Line $((URL_COUNT+1)) [${url}]: No -H/--hostname arg supplied for relative URL checking"
				exit 3
			fi
			RET=$($CHECK_HTTP $CHECK_COMMAND -u $url)
		else
			echo "Line $((URL_COUNT+1)): [$url] - Incorrect URL format."
			exit 3
		fi
		let URL_COUNT=$URL_COUNT+1
	done
	} < $1
	# if everything went fine above, we have a bunch of successful checks:
	RET="OK - $URL_COUNT URLs checked without failure"

fi

# echo back the $RET (displayed in Nagios)
echo $RET
# exit with result code (determines ok/warn/crit/unk)
exit $RES
