nrpe-bird/check_bird2_oneshot

199 lines
5.6 KiB
Bash
Executable file

#!/bin/sh
# Copyright 2021 alarig <alarig@grifon.fr>
#
# BSD-3-Clause licence
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. 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.
#
# 3. Neither the name of the copyright holder 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 HOLDER 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.
# For debuggin purpose, uncomment the next line and `tail -F` the file.
#exec 2> /tmp/check_bgp.log
# This scipt works with bird2 only
CONF_IGNORE_FILE="/usr/local/etc/nrpe-bird/ignore.cfg"
usage() {
printf "Usage:\n"
printf "Must be run with user account able to use birdc/birdc6 or "
printf "specify -s to use birdc with sudo.\n"
printf "To ignore sessions, put one per line in ${CONF_IGNORE_FILE}.\n"
}
args=$(getopt hs $*)
if [ $? -ne 0 ]; then
usage
exit 3
fi
set -- $args
while :; do
case "$1" in
-h)
usage
exit 0
shift;;
-s)
SUDO='sudo'
shift;;
--)
shift;
break;;
esac
done
birdc="${SUDO} birdc"
test_route_limit() {
if [ "${ROUTE_HIT_IN}" != "" ]; then
printf "${protocol_name} has hit import route " >> \
${DIR}/CRITICAL.txt
printf "limit\n" >> ${DIR}/CRITICAL.txt
elif [ "${ROUTE_HIT_OUT}" != "" ]; then
printf "${protocol_name} has hit export route " >> \
${DIR}/CRITICAL.txt
printf "limit\n" >> ${DIR}/CRITICAL.txt
elif [ ${RATIO_IN} -gt 92 ]; then
printf "${protocol_name} import route limit is " >> \
${DIR}/WARNING.txt
printf "over threshold\n" >> ${DIR}/WARNING.txt
fi
}
test_exstart_neigh() {
exstart_neighbors="$(${birdc} \
show ospf neighbors ${protocol_name} | grep -c ExStart)"
if [ "${exstart_neighbors}" -gt 0 ]; then
printf "${protocol_name} has " >> ${DIR}/WARNING.txt
printf "${exstart_neighbors} ExStart " >> ${DIR}/WARNING.txt
printf "neighbors\n" >> ${DIR}/WARNING.txt
fi
}
# path expansion for birdc and sudo of FreeBSD
PATH="$PATH:/usr/local/sbin/:/usr/local/bin/"
DIR="$(mktemp -d '/tmp/nrpe-bird.XXXX')"
#$birdc 'show protocols' | awk '$2 ~ "BGP" && $4 !~ "down" { print $0 }' > \
# ${DIR}/bgp_protocols_up.txt
# The sed removes the first two lines (BIRD 2.0.2 ready and Name Proto blah)
$birdc 'show protocols all' 2>${DIR}/bird-err | sed '1,2d;$d' | \
awk -v RS= -v DIR=$DIR '{print > (DIR "/" $1 ".txt")}'
if [ "$(cat ${DIR}/bird-err)" != '' ]; then
printf "ERROR: $(cat ${DIR}/bird-err)\n"
rm -r ${DIR}
exit 2
else
rm ${DIR}/bird-err
fi
for protocol in $(cat ${CONF_IGNORE_FILE}); do
rm "${DIR}/${protocol}.txt"
done
for protocol in $(find ${DIR} -type f); do
protocol_name=$(echo ${protocol} | cut -d / -f 4 | cut -d . -f 1)
STATE="$(head -n 1 ${protocol} | awk '{ print $6 }')"
ROUTE_LIMIT_IN="$(awk '/Import limit/ { print $3 }' ${protocol})"
ROUTES_IMPORTED="$(grep 'Routes:' ${protocol} | \
sed -Ee '/imported/{ s/^.* ([0-9]+) imported.*$/\1/; p;}' -e d)"
ROUTE_HIT_IN="$(grep -E 'Receive limit:.*HIT' ${protocol})"
if [ -z ${ROUTE_LIMIT_IN} ]; then
# There is no import limit, so no ratio either
RATIO_IN=0
else
RATIO_IN=$(echo "(${ROUTES_IMPORTED}*100)/${ROUTE_LIMIT_IN}" \
| bc)
fi
ROUTE_HIT_OUT="$(grep -E 'Export limit:.*HIT' ${protocol})"
# Plugin return codes:
# https://nagios-plugins.org/doc/guidelines.html#AEN78
case ${STATE} in
# BGP
# Session states:
# https://gitlab.labs.nic.cz/labs/bird/blob/master/proto/bgp/bgp.h#L601
Established | Passive)
test_route_limit
;;
OpenSent | OpenConfirm)
printf "${protocol_name} is in ${STATE} state\n" >> \
${DIR}/WARNING.txt
;;
Idle | Connect | Active)
printf "${protocol_name} is in ${STATE} state\n" \
>> ${DIR}/CRITICAL.txt
;;
# OSPF
# https://gitlab.labs.nic.cz/labs/bird/blob/master/proto/ospf/ospf.c#L532
Running)
test_route_limit
test_exstart_neigh
;;
Alone)
printf "${protocol_name} is in ${STATE} state\n" >> \
${DIR}/WARNING.txt
;;
# Or what
*)
if [ -z ${STATE} ]; then
printf "Empty state for ${protocol_name}\n" \
>> ${DIR}/UNKNOWN.txt
else
printf "Unknown state ${STATE} for " >> \
${DIR}/UNKNOWN.txt
printf "${protocol_name}\n" >> ${DIR}/UNKNOWN.txt
fi
;;
esac
done
if [ -f ${DIR}/CRITICAL.txt ]; then
printf "CRITICAL: $(cat ${DIR}/CRITICAL.txt)\n"
rm -r ${DIR}
exit 2
elif [ -f ${DIR}/WARNING.txt ]; then
printf "WARNING: $(cat ${DIR}/WARNING.txt)\n"
rm -r ${DIR}
exit 1
elif [ -f ${DIR}/UNKNOWN.txt ]; then
printf "UNKNOWN: $(cat ${DIR}/UNKNOWN.txt)\n"
rm -r ${DIR}
exit 3
else
printf "OK: This is fine\n"
rm -r ${DIR}
exit 0
fi