#!/bin/bash 
#
# check_k8s_node
#
# Author        : Nohaj
# Contact       : johan@slashroot.fr
# Date          : 19/02/19
# Version       : 1.0
# Description   : Basic script to check if a k8s node is running and then retrieve its status conditions
# Require       : jq and kubectl utility with a configured access to a k8s cluster
#

#
# Variables and checks
#

exit_code=0
message=""

# Checks and expected results are hardcoded =/
checks="MemoryPressure;False DiskPressure;False PIDPressure;False Ready;True"

# This script needs jq and kubectl
type jq &> /dev/null || { echo >&2 "UNKNOWN: This script need the jq utility to run."; exit 3; }
type kubectl &> /dev/null || { echo >&2 "UNKNOWN: This script need the kubectl utility to run."; exit 3; }

# Check kubectl command
if ( ! kubectl get nodes &> /dev/null ) ; then
    echo "UNKNOWN: Kubectl command doesn't seems to be working"
    exit 3
fi

usage (){
cat <<EOF

Usage : check_k8s_node -n NODE

Options:
    -h          Print help
    -n NODE     Name of the node to check

EOF
exit 3
}

#
# Let's go
#

while getopts ":n:h" opt; do
    case "$opt" in
        n)
            node="$OPTARG"
            ;;
        h) 
            usage 
            ;;
        *) 
            usage
            ;;
    esac
done

if [[ -z $node ]] ; then
    echo "UNKNOWN: You must provide one parameter and one only"
    exit 3
fi

# Retrieve state of the node
if ( kubectl get node $node &> /dev/null ) ; then
    state=$(kubectl get node $node --no-headers 2> /dev/null | awk -F" " '{print $2}')
    if [[ $state != "Ready" ]] ; then
        if [[ $state == "Ready,SchedulingDisabled" ]] ; then
            echo "WARNING: Node $node is Cordoned"
            exit 1
        else
            echo "CRITICAL: Node $node is not running (state: $state)"
            exit 2
        fi
    fi
else
    echo "UNKNOWN: Are you sure that $node is a k8s node ?"
    exit 3
fi

# If the node is running, we check its status conditions
for i in $checks ; do
    check=$(echo $i | cut -d ";" -f 1)
    expected_res=$(echo $i | cut -d ";" -f 2)
    res=$(kubectl get node $node -o json | jq .status.conditions[] | jq -r 'select(.type=="'$check'").status')
    
    if [[ $res != $expected_res ]] ; then
        exit_code=1
        message=""$message"WARNING: $check - $(kubectl get node $node -o json | jq .status.conditions[] | jq -r 'select(.type=="'$check'").message')\n"
    else
        message=""$message"OK: $check - $(kubectl get node $node -o json | jq .status.conditions[] | jq -r 'select(.type=="'$check'").message')\n"
    fi
done

# Print final result
if [[ $exit_code -eq 0 ]] ; then
    echo -e "OK: All the components are in a good state on node $node\n"
    echo -e $message
    exit 0
else
    echo -e "WARNING: One or more component is not in a good state on node $node\n"
    echo -e $message
    exit 1
fi
