Icinga Ampel –

Wir bei axxeo haben schon seit geraumer Zeit Icinga im Einsatz. Da Icinga seit längerem eine API anbietet und wir gerne eine Icinga USB Tisch-Ampel zum Anzeigen verschiedener Statusinformationen verwenden wollten, haben wir ein Ampel-Script erstellt.
Dieses Ampel-Script läuft auf einem Beaglebone Black mit der Linux-Distribution Debian 9.

Voraussetzungen zum Betreiben und Ansteuern der USB-Ampel sind:

Der erste Teil unseres Codes deklariert einige Variablen, spricht die API an und liefert den Status zurück. Hierbei werden Stati, welche “acknowledged” sind, ignoriert.

#! /bin/bash
# /usr/local/bin/ampel.sh
PATH=$PATH:/usr/local/bin

OK=0
WARNING=1
CRITICAL=2
UNKNOWN=3
FAILURE=4

declare -A COLORS=(
    [$OK]="GREEN"
    [$WARNING]="YELLOW"
    [$CRITICAL]="RED"
    [$UNKNOWN]="GREEN RED"
    [$FAILURE]="GREEN YELLOW RED"
)
call_api()
{
    # strip trailing 's'
    what=${1:0:-1}
    # Zugangsdaten müssen angepasst werden (default: icinga:icinga)
    curl -k -s -u icinga:icinga \
        -H 'Accept: application/json' \
        -H 'X-HTTP-Method-Override: GET' \
        -X POST 'https://icinga:5665/v1/objects/'${what}s \
        -d '{"attrs": ["state"], "filter": "'$what'.state && !'$what'.acknowledgement && !'$what'.downtime_depth"}'
}

Der zweite Teil wertet alle Hosts aus und liefert am Ende den höchsten gefundenen Status als “return-code” zurück.

get_states()
{
    local hosts services state rc=$OK

    hosts="$(call_api hosts)"
    [ ! "$hosts" ] && return $FAILURE
    while read state; do
        # host down = state 1
        [ $state -eq $WARNING ] && return $CRITICAL || rc=$state
    done < <(echo $hosts | jq -r '.results[].attrs.state')

    services="$(call_api services)"
    [ ! "$services" ] && return $FAILURE
    while read state; do
        case $state in
            $WARNING) rc=$WARNING ;;
            $CRITICAL) return $CRITICAL ;;
            $UNKNOWN) [ $rc -eq $OK ] && rc=$UNKNOWN ;;
        esac
    done < <(echo $services | jq -r '.results[].attrs.state')

    return $rc
}

Am Ende führen wir eine Endlosschleife aus, die unsere Ampel via “clewarecontrol” anspricht.

signal-cleware.sh init
signal-cleware.sh ${COLORS[$OK]}

rc_last=$OK
while true; do
    get_states; rc=$?
    if [ $rc -ne $rc_last ]; then
        echo $(date '+%F %T') ${COLORS[$rc]}
        signal-cleware.sh ${COLORS[$rc]}
        rc_last=$rc
    fi
    sleep $SLEEP
done

# should never arrive here
exit 1

Zum Schluss noch das Programm, dass die Ampel selbst ansteuert.

#! /bin/bash
# /usr/local/bin/signal-cleware.sh
# usage: $0 [GREEN [YELLOW [RED]]] (case ins.)

declare -A SWITCHES=([GREEN]=2 [YELLOW]=1 [RED]=0)

signal()
{
    local color=$1 state=$2

    clewarecontrol -c 1 -d 904756 -as ${SWITCHES[$color]} $state >/dev/null 2>&1
}

init()
{
    for color in ${!SWITCHES[*]}; do
       signal $color 1
       signal $color 0
    done
}

if [ x$1 == xinit ]; then
    init
else
    for color in ${!SWITCHES[*]}; do
        [[ ${*^^} =~ $color ]] && signal $color 1 || signal $color 0
    done
fi

Icinga Ampel