File check_keepalived of Package monitoring-plugins-keepalived

#!/bin/bash
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
#
# * Neither the name of the Novell nor the names of its contributors may be
#   used to endorse or promote products derived from this software without
#   specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#

export PATH="/usr/local/bin:/usr/bin:/bin"

REVISION=0.1.5
PROGNAME=$(basename "$0")
PROGPATH=$(dirname "$PROGNAME")
#STATEFILE='/var/run/keepalived.state'
STATEFILE='/tmp/keepalived.stats'
PIDFILE='/var/run/keepalived.pid'
STATE='UNKOWN - no data processed'
PROGPATH='/usr/lib/nagios/plugins/'
USE_SNMP=false
SNMP_VERSION='2c'
SNMP_HOSTNAME='localhost'
SNMP_COMMUNITY='public'
SNMP_WALK='/usr/bin/snmpwalk'
AWK='/usr/bin/awk'
TR='/usr/bin/tr'
KEEPALIVED_INSTANCE_STATE_OID='.1.3.6.1.4.1.9586.100.5.2.3.1.4.1'
KEEPALIVED_WANTED_STATE_OID='.1.3.6.1.4.1.9586.100.5.2.3.1.6.1'

if [ -r "$PROGPATH/utils.sh" ]; then
    . "$PROGPATH/utils.sh"
fi

print_usage() {
    echo "Usage: $PROGNAME [-F keepalived_statefile] [-p keepalived_pidfile] [-S|-M] [-h] [-v]"
    echo "       -F keepalived_statefile : URI to the status file (default: $STATEFILE)"
    echo "       -p keepalived_pidfile   : URI to the pidfile of the keepalived process (default: $PIDFILE)"
    echo "       -S                      : expect the machine to run in SLAVE state"
    echo "       -M                      : expect the machine to run in MASTER state"
    echo "       -h                      : print this usage"
    echo "       -V                      : print version information"
    echo "       -s                      : use SNMP"
    echo "       -H <hostname>           : SNMP host to query"
    echo "       -v <snmp_version>       : SNMP version (currently only 2c is supported, therefor default)"
    echo "       -c <snmp_community>     : SNMP v2 community string"
    echo
    echo "To successfully run this script via the 'notify'-script configuration, the following pre-requires need to be fulfilled:"
    echo "* in your keepalived.conf, add 'notify /usr/bin/keepalived_notify_monitoring.sh'" 
    echo "  in at least one vrrp_instance section (see 'keepalived_notify_monitoring.sh -h'"
    echo "  output for more details"
    echo
    echo "In case of using the SNMP option, the following pre-requires need to be fulfilled:"
    echo "* a running SNMP daemon with agentx support"
    echo "* keepalived needs to be started with the '-x' or '--snmp' option"
    echo 
    echo "In any of the above options:"
    echo "* keepalive should be restarted after the changes"
    echo
    echo "Check https://en.opensuse.org/Monitoring-plugins-keepalived for more information."
    echo    
}

print_help() {
    print_revision $PROGNAME $REVISION
    echo
    print_usage
    echo
    support
    exit $STATE_OK
}

while getopts 'F:p:SMhVv:sH:c:' OPTION ; do
    case $OPTION in
        v|V)
            print_revision $PROGNAME $REVISION
            exit $STATE_OK
        ;;
        F)
            STATEFILE="$OPTARG"
        ;;
        M)
            MASTER='true'
        ;;
        p)
            PIDFILE="$OPTARG"
        ;;
        S)
            SLAVE='true'
        ;;
        h)
            print_help
            exit $STATE_OK
        ;;
        s)
            USE_SNMP=true
        ;;
        H)
            SNMP_HOSTNAME="$OPTARG"
        ;;
        v)
            SNMP_VERSION="$OPTARG"
        ;;
        c)
            SNMP_COMMUNITY="$OPTARG"
        ;;
        *)
            echo "Unkown argument: $OPTION" >&2
            print_usage
            exit $STATE_UNKNOWN
        ;;
    esac
done

if [ -r "$PIDFILE" ]; then
    PID=$(cat "$PIDFILE")
    KEEPALIVERUN=$(cat "/proc/$PID/status" | grep ^State: | awk '" " { print $2 }')
    case $KEEPALIVERUN in
        S|R)
            KEEPALIVESTATE=$STATE_OK
        ;;
        Z)
            echo "WARNING: main keepalived process is a Zombie"
            exit $STATE_WARNING
        ;;
        *)
            echo "UNKOWN: found $PIDFILE but got no state for keepalived"
            exit $STATE_UNKNOWN
        ;;
    esac
else
    KEEPALIVENUM=$(ps ax | grep [k]eepalived | wc -l | $TR -d "\n")
    if [ $KEEPALIVENUM -gt 0 ]; then
        KEEPALIVESTATE=$STATE_OK
    fi
fi

if [ $KEEPALIVESTATE -eq $STATE_OK ]; then
  if [ $USE_SNMP == "true" ]; then
	for command in $AWK $SNMP_WALK $TR ; do
		if [ ! -x $command ]; then
			echo "ERROR: $command not found or not executable"
			exit $STATE_CRITICAL
		fi
	done
	# snmpwalk -On -v2c -cpublic localhost .1.3.6.1.4.1.9586.100.5.2.3.1.4.1
	SNMP_CURRENT_STATE=$($SNMP_WALK -v${SNMP_VERSION} -c${SNMP_COMMUNITY} $SNMP_HOSTNAME $KEEPALIVED_INSTANCE_STATE_OID | $AWK ' { print $4 }')
	case $SNMP_CURRENT_STATE in
		*1*) STATE="SLAVE" ;;
		*2*) STATE="MASTER" ;;
		*) STATE="UNKNOWN" ;;
	esac
	if [ "$MASTER" == "true" ]; then
		if [ "$STATE" = "MASTER" ]; then
			echo "OK: $SNMP_HOSTNAME is master"
			exit $STATE_OK
		else
			echo "CRIT: $SNMP_HOSTNAME is not master (state is: $STATE)"
			exit $STATE_CRITICAL
		fi
	elif [ "$SLAVE" == "true" ]; then
		if [ $STATE = "SLAVE" ]; then
			echo "OK: $SNMP_HOSTNAME is slave"
			exit $STATE_OK
		else
			echo "CRIT: $SNMP_HOSTNAME is not slave (state is: $STATE)"
			exit $STATE_CRITICAL
		fi
	else
		# snmpwalk -On -v2c -cpublic localhost .1.3.6.1.4.1.9586.100.5.2.3.1.6.1
		SNMP_WANTED_STATE=$($SNMP_WALK -v${SNMP_VERSION} -c${SNMP_COMMUNITY} $SNMP_HOSTNAME $KEEPALIVED_WANTED_STATE_OID | $AWK ' { print $4 }')
		if [ "$SNMP_CURRENT_STATE" = "$SNMP_WANTED_STATE" ]; then
			echo "OK: $SNMP_HOSTNAME is in wanted state (state is: $STATE)"
			exit $STATE_OK
		else
			echo "CRIT: $SNMP_HOSTNAME is not in wanted state (state is: $STATE)"
			exit $STATE_CRITICAL
		fi
	fi

  else
    rm -f $STATEFILE
    kill -USR2 $PID
    sleep 1
    if [ -r "$STATEFILE" ] ; then
        STATE1=$(grep "Became master:" "$STATEFILE")
        STATE2=$(grep "Released master:" "$STATEFILE")
    else
        echo "UNKOWN: could not read $STATEFILE"
        exit $STATE_UNKNOWN
    fi
    rm -f $STATEFILE
    if [[ $STATE1 == *"Became master: 0"* ]];then
        echo "$STATE1"
        exit $STATE_CRITICAL
    fi

    if [ "$MASTER" == "true" ]; then
        if [[ $STATE2 == *"Released master: 0"* ]]; then
            echo "$STATE1 $STATE2"
            exit $STATE_OK
        fi
        if [[ $STATE2 == *"Released master: 1"* ]]; then
            echo "$STATE1 $STATE2"
            exit $STATE_CRITICAL
        fi
    elif [ "$SLAVE" == "true" ]; then
        if [[ $STATE2 == *"Released master: 1"* ]]; then
            echo "$STATE1 $STATE2"
            exit $STATE_OK
        elif [[ $STATE2 == *"Released master: 0"* ]]; then
            echo "$STATE1 $STATE2"
            exit $STATE_CRITICAL
	else
            echo "UNKOWN: could not detect state from $STATEFILE : $STATE1 $STATE2"
            exit $STATE_UNKNOWN
        fi
    else
        if [[ $STATE2 == *"Released master: 0"* ]] || [[ $STATE2 == *"Released master: 1"* ]]; then
            echo "$STATE1 $STATE2"
            exit $STATE_OK
	else
            echo "UNKOWN: could not detect state from $STATEFILE : $STATE1 $STATE2"
            exit $STATE_UNKNOWN
        fi
    fi
  fi
else
    echo "Keepalived is in UNKNOWN state"
    exit $STATE_UNKNOWN
fi
openSUSE Build Service is sponsored by