#!/bin/bash

# Author: Juul Spies
# Very simple script which compares etc/fstab to proc/mounts

STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
RESULT=`mktemp`

FILTEREDFSTAB=`mktemp`


# Set to anything but 'no' to enable verbose output, not suitable for Nagios/Icinga
DEBUG=no


function debug {
    [ "$DEBUG" = "no" ] && return
    echo "$*"
}


function check_mountopts {
    echo "Hier de mountopties checken, dat gaan we nog bouwen"
}


function check_nfs {
    NFSRESULT=`cat /proc/mounts | sed -e 's#//#/#g' | grep "^${1}\s"`
    if [ -z "${NFSRESULT}" ]; then
        echo "${1} not mounted" >>  ${RESULT}
    else
        echo ${NFSRESULT} | while read TABMOUNT TABPOINT TABTYPE TABOPTS;
        do
            [ "$2" == "$TABPOINT" ] || echo "${1} is not mounted on ${TABPOINT}" >> ${RESULT}
        done
    fi
}


function check_localfs {
    # We need to convert UUID to regular devices or dm devices first
    if `grep -E -q ^UUID <<< ${1}`; then
        UUID=`sed -e 's/^UUID=//' -e 's/"//g' <<< ${1}`
        debug "UUID is: ${UUID}"

        UUDISK=`blkid -U ${UUID}`
        debug "Device is: ${UUDISK}"

        # Als het UUID inmiddels reguliere disk is vinden we het mooi en kunnen we $DISK zetten
        if `grep -E -q '^/dev/sd|^/dev/hd|^/dev/vd|^/dev/md|^/dev/mapper/' <<< ${UUDISK}`; then
            debug "Seems to be regular device now."
            DISK=${UUDISK}
        fi
    fi
    if `grep -E -q '^/dev/sd|^/dev/hd|^/dev/vd|^/dev/md|^/dev/mapper/' <<< ${1}`; then
        debug "Seems to be regular device. Not a UUID: '${1}'"
        DISK=${1}
    fi

    if [ -z ${DISK} ]; then
        debug "Disk variable was still empty. Failed to convert UUID or find DM node?"

        # Work with 1 variable
        if [ -z ${UUDISK} ]; then
            DMDISK=${1}
        else
            DMDISK=${UUDISK}
        fi

        debug "Going with DMDISK '$DMDISK' ..."

        # DMDISK needs to broken down to /dev/dm$ if it is not already
        if ! `grep -E -q '^/dev/dm' <<< ${DMDISK}`; then
            DMDISK=`readlink -f ${DMDISK}`
        fi
    
        # We should have a /dev/dm$ device now
        if `grep -E -q '^/dev/dm' <<< ${DMDISK}`; then
            DISKRESULT=`cat /proc/mounts | sed -e 's#//#/#g' | grep "^${DMDISK}"`
        fi
        debug "DeviceMapper device disk result is: ${DISKRESULT}"

    else
        # Blijkbaar hebben we een fatsoenlijke disk, mooi!
        DISKRESULT=`cat /proc/mounts | sed -e 's#//#/#g' | grep "^${DISK}"`
        if [ -z "${DISKRESULT}" ]; then
            DMDISK=`readlink -f ${DISK}`
            DISKRESULT=`grep "^${DMDISK}" /proc/mounts`
        fi

        debug "Regular device disk result is: '${DISKRESULT}'"
    fi


    if [ -z "${DISKRESULT}" ]; then
        echo "${1} not mounted" >>  ${RESULT}
    else
        echo ${DISKRESULT} | while read TABMOUNT TABPOINT TABTYPE TABOPTS;
        do
            [ "$2" == "$TABPOINT" ] || echo "${1} is not mounted on ${TABPOINT}" >> ${RESULT}
        done
    fi

}


# Skip alles wat start met een comment, wat start met proc, skip alles met swap en noauto erin.
grep -E -v '^#|^proc|swap|noauto"' /etc/fstab | awk '{print $1" "$2" "$3" "$4}' | grep -v "^[[:space:]]*$" > ${FILTEREDFSTAB}


cat ${FILTEREDFSTAB} | while read MOUNT POINT TYPE OPTS;
do
#    echo "Mount: ${MOUNT}, Point: ${POINT}, Type: ${TYPE}, Options: ${OPTS}"
    MOUNT=`sed "s,/$,," <<< ${MOUNT}`
    if [ "${TYPE}" == "nfs" ] && ! `grep -E -q 'noauto' <<< ${OPTS}`; then
        check_nfs ${MOUNT} ${POINT} ${OPTS}
    fi
    # for now check ext + xfs
    if `grep -E -q 'ext|xfs' <<< ${TYPE}` && ! `grep -E -q 'noauto' <<< ${OPTS}`; then
        check_localfs ${MOUNT} ${POINT} ${OPTS}
    fi
done

if grep -q "not mounted\|but not on correct" ${RESULT}; then
    printf "CRITICAL: "
    while read -r in; do
        printf "%s " "$in"
    done < ${RESULT}
    printf "\n"
    rm ${FILTEREDFSTAB} ${RESULT}
    exit ${STATE_CRITICAL}
else
    echo "OK: all paths on correct targets"
    rm ${FILTEREDFSTAB} ${RESULT}
    exit ${STATE_OK}
fi

rm ${FILTEREDFSTAB} ${RESULT}
echo "WARNING: Check should not end here, please investigate"
exit ${STATE_WARNING}
