#!/bin/bash
#
# check_k8s_storageos_pvc
#
# Author        : Nohaj
# Contact       : johan@slashroot.fr
# Date          : 21/03/19
# Version       : 1.4 (12/11/19)
# Description   : Basic script to check the storageos pvc usage inside a kubernetes cluster
# Require       : Access to the storageos API of all storageos nodes
#

#
# CHANGELOG
#
# v1.1 : fix the OK print result where there is issues
#        print result with 2 numbers after the float
#
# v1.2 : fix the print result where there is mixed warning and criticals
#
# v1.3 : on ne fait plus qu'un curl et on ne controle que les volumes master
#
# v1.4 : on filtre les pvc sur node_volumes_total et non plus sur volume_utilisation_apparent_bytes car les volumes vides n'etaient pas remontes
#

#
# Variables and checks
#

# Defaults thresolds
warn_thresold=80
crit_thresold=90

# pvs number
pvs=0
exit_code=0

# count variables
warn_volume=0
crit_volume=0

# tmp file to store results
tmpfile=$(mktemp /tmp/abc-script.XXXXXX)

usage (){
cat <<EOF

Usage : check_k8s_storageos_pvc -n NODE1,NODE2,NODE3... [-w WARN_THRESOLD] [-c CRIT_THRESOLD] 

Options:
    -h                        Print help
    -n NODE1,NODE2,NODE3...   StorageOS nodes to check persistents storage on
    -w WARN_THRESOLD          Warning usage threshold (default : $warn_thresold)
    -c CRIT_THRESOLD          Critical usage threshold (default : $crit_thresold)
EOF
exit 3
}


#
# Let's go
#

while getopts "n:h:w:c:" opt; do
    case "$opt" in
        n)
            nodes="$OPTARG"
            ;;
        w)
            warn_thresold="$OPTARG"
            ;;
        c)
            crit_thresold="$OPTARG"
            ;;
        h)
            usage
            ;;
        *)
            usage
            ;;
    esac
done

# On verifie que les noeuds storageos sont bien passes en parametre
if [[ -z $nodes ]] ; then
    echo "UNKNOWN: No nodes specified. Please check the command usage"
    exit 3
fi

# On parcours chaque noeud a la recherche des pvc qu'ils herbergent et on calcule l'usage
OLDIFS="$IFS"
IFS=$','
for node in $nodes ; do
    IFS="$OLDIFS"
    curl -s $node:5705/metrics > $tmpfile
    pvcs=$(grep node_volumes_total $tmpfile | tail -n +2 | grep 'type="master"' | cut -d "=" -f 6 | cut -d '"' -f 2)
    if [ -n "$pvcs" ] ; then
        IFS="$OLDIFS"
        for pvc in $pvcs ; do
            pvs=$((pvs+1))
            size=$(grep $pvc $tmpfile | grep volume_size_bytes | cut -d " " -f 2)
            usage=$(grep $pvc $tmpfile | grep $pvc | grep volume_utilisation_apparent_bytes | cut -d " " -f 2)
            size_b=$(echo $size | perl -ne 'printf "%d\n", $_;')
            size_g=$(echo "$size_b / 1024 / 1024 / 1024" | bc )
            usage_b=$(echo $usage | perl -ne 'printf "%d\n", $_;')
            usage_g=$(echo "scale=2; $usage_b / 1024 / 1024 / 1024" | bc -l | sed 's/^\./0./')
            perc_util=$(echo "scale=2; $usage_b * 100 / $size_b" | bc -l | sed 's/^\./0./')
            perc_util_nofloat=$(echo $perc_util |cut -d '.' -f 1)
            if [[ $perc_util_nofloat -gt $crit_thresold ]] ; then
                crit=1
                crit_volume=$((crit_volume+1))
                err_message="$err_message$perc_util% ("$usage_g"G/"$size_g"G) - $pvc ($node)\n"
            elif [[ $perc_util_nofloat -gt $warn_thresold ]] ; then
                warn=1
                warn_volume=$((warn_volume+1))
                warn_message="$warn_message$perc_util% ("$usage_g"G/"$size_g"G) - $pvc ($node)\n"
            else
                message="$message$perc_util% ("$usage_g"G/"$size_g"G) - $pvc ($node)\n"
                ok=$((ok+1))
            fi
        done
    fi
done
IFS="$OLDIFS"
rm -f $tmpfile

# On affiche le resutat selon les donnees recuperees
if [[ $crit -eq 1 ]] ; then
    if [[ $crit_volume -eq 1 ]] ; then
        echo "CRITICAL: 1 volume is above the critical thresold"
    else
        echo "CRITICAL: $crit_volume volume(s) are above the critical thresold"
    fi
    exit_code=2
    echo -e $err_message |sort -nr
fi

if [[ $warn -eq 1 ]] ; then
    if [[ $warn_volume -eq 1 ]] ; then
        echo "WARNING: 1 volume is above the warning thresold"
    else
        echo "WARNING: $warn_volume volume(s) are above the warning thresold"
    fi
    if [[ $exit_code -ne 2 ]] ; then
        exit_code=1
    fi
    echo -e $warn_message | sort -nr
fi

if [[ $pvs -eq 0 ]] ; then
    echo "UNKNOWN: We didn't find any volumes"
    exit 3
fi

err=$((crit_volume+warn_volume))
if [[ $pvs -gt $err ]] ; then
    echo "OK: $ok volumes are below thresolds"
    echo -e $message | sort -nr
else
    echo "UNKNOWN: We didn't find any volumes"
    exit 3
fi

exit $exit_code