#!/bin/bash

#################################################################################
#                                                                               #
#                  ALL THIS SCRIPT IS UNDER GPL LICENSE                         #
# Version 0.2                                                                   #
# Title:     ntpd                                                               #
# Author:    Alexander Bech  (alex |at| bakarasse |dot| de)                     #
# Date:      2010-01-22                                                         #
# Purpose:   Check ntpd status and clock diff                                   #
# Platforms: Uni* having ntpdate                                                #
# Tested:    Xymon 4.2.3 / ntpdate 4.2.0, 4.2.2, 4.2.4                          #
#                                                                               #
# History:                                                                      #
# 22/02/2010                                                                    #
# Version 0.2 - Make compatible with BBLOCATION variable.                       #
#                                                                               #
# 12/02/2010                                                                    #
# Version 0.1 - Initial write.                                                  #
#                                                                               #
#################################################################################

LC_ALL=C
LANG=C
LANGUAGE=C

    BBLOCATION="${XYMONNETWORK}"
    # 
    # BBLOCATION must be set.
    if [ -z ${BBLOCATION} ]
    then
	echo "$0 No BBLOCATION set. Exit."
	exit 0
    fi

    NTPDATE="/usr/sbin/ntpdate"
    if [ ! -x ${NTPDATE} ]
    then
        echo "$0 ERROR: ${NTPDATE} not found"
        exit 0
    fi

    BBHTAG=ntpd
    COLUMN=${BBHTAG}
    NTPTRACE="${NTPDATE} -4 -t 1 -p 1 -u -q"

    declare -i NTPWARN="1"
    declare -i NTPPANIC="2"
    declare -i OFFSET_SECONDS

    ALERT_NTPD_DOWN_OR_UNREACHABLE_COLOR="red"
    ALERT_NTPD_UNSYNCED_COLOR="yellow"
    ALERT_LOCAL_SERVER_CLOCK_UNSYNCED_COLOR="blue"

    if [ "${BBLOCATION}" = "CENTRAL" ]
    then
	# We are a central Server. Test all hosts with ntpd tag except other locations.
	HOSTLIST=$(${BBHOME}/bin/xymongrep --net --test-untagged ${BBHTAG})
    else
	# Wa are distributed test-agent. Test only hosts with my BBLOCATION tag.
	HOSTLIST=$(${BBHOME}/bin/xymongrep --net ${BBHTAG})
    fi
    if [ "${HOSTLIST}" = "" ]
    then
	echo "No hosts with ${BBHTAG} tag found in ${BBHOME}/etc/hosts.cfg"
	exit 0
    fi

    #debug:
    #echo "$HOSTLIST"

    ORIGIFS=${IFS}; IFS=$'\n'
    for LINE in ${HOSTLIST}
    do
	IFS=${ORIGIFS}
        set -- ${LINE}	# To get one line of output from bbhostgrep
	
        HOSTIP="$1"
        MACHINE="$2"
	TAG="$4"
	DIALUP="$5"

        MSG=""
        OFFSETMSG=""
	COLOR="green"
	if echo "${LINE}" | ${GREP} -q "testip"; then
    	    CATCH_COMMAND=$(${NTPTRACE} ${HOSTIP} 2>&1)
	    RESULT=$?
	    HOSTSTRING="${HOSTIP}"
	else
    	    CATCH_COMMAND=$(${NTPTRACE} ${MACHINE} 2>&1)
	    RESULT=$?
	    HOSTSTRING="${MACHINE}"
	    HOSTIP=$(echo "${CATCH_COMMAND}" | ${GREP} "^server" | ${AWK} '{print $2}')
	fi

	 OFFSET=$(echo "${CATCH_COMMAND}" | ${GREP} "^server" | ${GREP} "${HOSTIP}" | ${AWK} '{print $6}' | ${SED} 's/,//')
	STRATUM=$(echo "${CATCH_COMMAND}" | ${GREP} "^server" | ${GREP} "${HOSTIP}" | ${AWK} '{print $4}' | ${SED} 's/,//')
	
	#debug
	#echo "===$CATCH_COMMAND==="
	#echo "OFFSET=$OFFSET"
	#echo "STRATUM=$STRATUM"
	#echo "RESULT=$RESULT" 

	if [ "${RESULT}" = "0" ] ; then
	    # found server and could update the clock
	    COLOR="green"
	    MSG="&${COLOR} ntpd on ${HOSTSTRING} is up and synchronised"
	    
	else
	    # result non zero ...
	    COLOR="${ALERT_NTPD_DOWN_OR_UNREACHABLE_COLOR}"
	    if [ "$(echo "${CATCH_COMMAND}" | ${GREP} -i "^server.*stratum 0")" != "" ]
	    then
	    	MSG="&red ntpd on ${HOSTSTRING} is down or unreachable"
	    fi
	    # ... attemt to find reason ...
	    if [ "$(echo "${CATCH_COMMAND}" | ${GREP} -i "can't find host")" != "" ]
	    then
	    	MSG="&red can't find host ${HOSTSTRING}"
	    fi
	    if [ "$(echo "${CATCH_COMMAND}" | ${GREP} -i "Operation not permitted")" != "" ]
	    then
	    	MSG=$(echo -e "${NTPTRACE} ${HOSTSTRING}\n&red sendto: Operation not permitted")
	    fi
	    # if... other reasons ?
	    # fi
	    
	    # Query the BBDISP for the latest conn status from ${MACHINE}
	    CONNSTATUS=$(${BB} ${BBDISP} "query ${MACHINE}.conn")
	    set -- ${CONNSTATUS}
	    if [ "$1" = "red" ] ; then
		# if conn check active and failed, set color clear
		COLOR="clear"
		MSG="&red ntpd on ${HOSTSTRING} is down or unreachable and ping failed"
	    fi
	    if [ "$1" = "blue" ] ; then
		if [ "$(echo "${CONNSTATUS}" | ${GREP} "conn NOT ok")" != "" ]
		then
		    # if conn check active and red conn status disabled, set color clear
		    COLOR="clear"
		    MSG="&red ntpd on ${HOSTSTRING} is down or unreachable and conn status disabled"
		fi
	    fi

	    if [ "${DIALUP}" = "dialup" -o "${TAG}" = "?${BBHTAG}" ] ; then
		# if dialup host or ? prefix, set color clear
		COLOR="clear"
		MSG="&red ntpd on ${HOSTSTRING} is down or unreachable, dialup host or test ? prefixed"
	    fi
	    
	    # ntpd not synced
	    if [ "$(echo "${CATCH_COMMAND}" | ${GREP} -i "stratum 16")" != "" ]
	    then
	    	COLOR="yellow"
	    	MSG="&${COLOR} ntpd on ${HOSTSTRING} is up, but not synchronised!!!"
	    fi
	    
	    # ntpd daemon in sync, but local clock not synced
	    if [ "${STRATUM}" != "0" -a "${STRATUM}" != "16" ]
	    then
	    	if [ "$(echo "${CATCH_COMMAND}" | ${GREP} "no server suitable for synchronization found")" != "" ]
		then
	    	    COLOR="${ALERT_LOCAL_SERVER_CLOCK_UNSYNCED_COLOR}"
	    	    MSG="&${COLOR} ntpd on ${HOSTSTRING} is up, but local clock is not synced."
	    	fi
	    fi
	fi

if [ "${OFFSET}" != "" -a "${STRATUM}" != "" ]; then
    # Offset check:
    OFFSET_SECONDS=$(echo ${OFFSET} | ${SED} 's/-//' | ${SED} 's/\./ /' | ${AWK} '{print $1}')
    if [ "${OFFSET_SECONDS}" -ge "${NTPWARN}" ] ; then
        COLOR="yellow"
        OFFSETMSG="&${COLOR} Clock diff is ${OFFSET_SECONDS} sec."
    fi 
    if [ "${OFFSET_SECONDS}" -ge "${NTPPANIC}" ] ; then
        COLOR="red"
        OFFSETMSG="&${COLOR} Clock diff is ${OFFSET_SECONDS} sec."
    fi

MSG="${MSG}
${OFFSETMSG}

Stratum : ${STRATUM}
Offset  : ${OFFSET}
"
fi

${BB} ${BBDISP} "status ${MACHINE}.${COLUMN} ${COLOR} `date`
${MSG}
"

#debug:
echo "${MACHINE} = ${COLOR}"
#echo "${LINE}"
#echo "${CATCH_COMMAND}"
#echo "${BB} ${BBDISP} status ${MACHINE}.${COLUMN} ${COLOR}"
#echo "${MSG}"

done
