#!/bin/bash

# check_haproxy_loalias.sh - check lo's aliases according to configs in /etc/haproxy/conf.d

# This script will check if any of the lo's (127.0.0.1) aliases used in
# haproxy LVS/dynamic routing environment are down. The aliases are defined
# in /etc/haproxy/conf.d/ directory, in files named like this:
#
# loalias-193.200.227.65 (something dash IP)
#
# This is actually this script: http://www.orfika.net/src/loalias-script.sh)

# Copyright 2011 Rafał Frühling <rafamiga@gmail.com>

# last revision: $Date: 2011-04-01 13:48:04 +0200 (pią) $ (and it's not a joke!)

# LICENCE: GPL
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# you should have received a copy of the GNU General Public License
# along with this program (or with Nagios); if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA

PROGNAME=`basename $0`
PROGPATH=`echo $0 | /bin/sed -e 's,[\\/][^\\/][^\\/]*$,,'`
REVISION=`echo '$Revision: 9897 $' | sed -e 's/[^0-9.]//g'`

ip_exe=/sbin/ip

STATE_UNKNOWN=3
STATE_CRITICAL=2
STATE_WARNING=1
STATE_OK=0

print_usage() {
    echo "Usage: ${PROGNAME} -h"
    echo "Usage: ${PROGNAME} -v"
    echo "Usage: ${PROGNAME} [-d DIRECTORY] [-f]"
    echo ""
    echo "    -d <directory>: the directory in which to look for aliases (default: /etc/haproxy/conf.d)"
    echo "    -i <interface}: look for aliases of this interface (default: lo)"
    echo "    -a <ip>: main IP address of the interface (with netmask; default: 127.0.0.1/8)"
    echo "    -f: fail if IP are missing (default: warn)"
    echo "    -6: check IPv6 addresses as well as IPv4"
    }
 
print_help() {
    print_revision "$PROGNAME" $REVISION
    echo ""
    print_usage
    echo ""
    echo "Plugin to check if all of an interface aliases (default: lo - loopback), as defined in /etc/haproxy/conf.d directory, are up."
    echo ""
    }

## No command line arguments are supplied for this script. Print help.
#
#if [ "$#" -eq "0" ]; then
#    print_usage
#    exit ${STATE_UNKNOWN}
#fi

# Print help with --help

if [[ ("$#" -eq "1") && ("$1" = "--help") ]]; then
    print_help
    exit ${STATE_UNKNOWN}
fi

HAPROXY_EXTRACONF_DIR=/etc/haproxy/conf.d
INT_SRC=lo
FAIL_MISSING=0
USE_IPV6=0
INT_ADDR="127.0.0.1/8"

script_glob=${INT_SRC}alias

while getopts "vhf6d:i:a:" option
do
    case ${option} in
        h     ) print_help
            exit ${STATE_UNKNOWN};;
        v     ) print_revision "${PROGNAME}" ${REVISION}
            exit ${STATE_UNKNOWN};;
        f     ) FAIL_MISSING=1;;
        d     ) HAPROXY_EXTRACONF_DIR=${OPTARG};;
        i     ) INT_SRC=${OPTARG};;
        a     ) INT_ADDR=${OPTARG};;
        6     ) USE_IPV6=1;;
        *     ) print_usage
            exit ${STATE_UNKNOWN};;   # DEFAULT
    esac
done

if [ ! -d "${HAPROXY_EXTRACONF_DIR}" ] || [ ! -r "${HAPROXY_EXTRACONF_DIR}" ]; then
    echo "UNKNOWN - HAPROXY extra config directory '${HAPROXY_EXTRACONF_DIR}' is missing or unreadable by '${USER}' user."
    exit ${STATE_UNKNOWN}
fi

if [ ! -x ${ip_exe} ]; then
    echo "UNKNOWN - can't run plugin, '${ip_exe}' binary not found or unreadable by '${USER}' user."
    exit ${STATE_UNKNOWN}
fi

TRACE=`${ip_exe} addr list dev ${INT_SRC} 2>&1`

if [ -z "${TRACE}" ]; then
    echo "UNKNOWN - can't run plugin, either interface '${INT_SRC}' does not exist or '${ip_exe}' binary failed to gather information about it."
    exit ${STATE_UNKNOWN}
fi

haproxy_conf_d_files=`dir -BU "${HAPROXY_EXTRACONF_DIR}"`

if [ -z "${haproxy_conf_d_files}" ]; then
    echo "WARNING - no files found in '${HAPROXY_EXTRACONF_DIR}'"
    exit ${STATE_WARNING}
fi

MISSING_IPS=""

for intf in ${haproxy_conf_d_files}; do
    scriptname=${intf%%-*}
    ipalias="${intf#*-}"

    # not a "loalias" file
    if [ "${scriptname}" != "${script_glob}" ]; then
        continue
    fi

    if [ "${ipalias}" == "${ipalias#*/}" ]; then
        ipalias="${ipalias}/32"
    fi

    CHECKED_OK=`echo "${TRACE}" | grep -q -F ${ipalias}`

    if [ $? -ne 0 ]; then
        MISSING_IPS="${ipalias} ${MISSING_IPS}"
    fi
done

if [ -n "${MISSING_IPS}" ]; then
    if [ ${FAIL_MISSING} -eq 0 ]; then
        echo "WARNING - missing IP(s) on interface '${INT_SRC}': ${MISSING_IPS}"
        exit ${STATE_WARNING}
    else
        echo "CRITICAL - missing IP(s) on interface '${INT_SRC}': ${MISSING_IPS}"
        exit ${STATE_CRITICAL}
    fi
fi
    
echo "OK - interface '${INT_SRC}' alias(es) OK."
exit ${STATE_OK}
