#!/bin/bash
# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

#The MIT License (MIT)
#Henry Huang (http://blog.unicsolution.com)
#Most updated file: https://github.com/bbhenry/check_mk_local/edit/master/check_mount_rw

PROGNAME=$(basename "$0")
REVISION="1.0"
FQDNNAME=$(hostname -f)
TESTFILE="test-rw-$FQDNNAME"
RAND=$RANDOM

print_usage() {
    echo "Usage: $PROGNAME"
}

print_help() {
    print_revision "$PROGNAME" $REVISION
    echo ""
    print_usage
    echo ""
    echo "This plugin will write temporary file to all detected nfs and glusterfs directories and read them to verify the network mount points are working without fail"
    echo ""
    exit 0
}

check_mount_rw() {
    # FIXME: Prefer mapfile or read -a to split command output (or quote to avoid splitting).
    # shellcheck disable=SC2207
    MOUNTPOINTS=($(grep -E 'glusterfs|nfs' /proc/mounts | awk '{ gsub("fuse.glusterfs","glusterfs",$3); print $2":"toupper($3) }'))

    for a in "${MOUNTPOINTS[@]}"; do
        DIRECTORY=$(echo "$a" | cut -f1 -d:)
        CONNECTIONTYPE=$(echo "$a" | cut -f2 -d:)

        timeout 1s ls "$DIRECTORY"/"$TESTFILE"
        RET_V=$?
        if [[ $RET_V -eq 124 || $RET_V -eq 137 ]]; then
            echo "2 Mount_${CONNECTIONTYPE}_RW_:$DIRECTORY - Accessing mount point $DIRECTORY timed out"
            continue
        elif [[ $RET_V -eq 0 ]]; then
            echo "2 Mount_${CONNECTIONTYPE}_RW_:$DIRECTORY - Test file $DIRECTORY/$TESTFILE already exist"
            rm -f "$DIRECTORY"/"$TESTFILE"
            continue
        fi

        timeout 1s echo $RAND >"$DIRECTORY"/"$TESTFILE"
        RET_W=$?
        if [[ $RET_W -eq 124 || $RET_W -eq 137 ]]; then
            echo "2 Mount_${CONNECTIONTYPE}_RW_:$DIRECTORY - Writing test file to $DIRECTORY/$TESTFILE timed out"
            continue
        elif [[ $RET_W -ne 0 ]]; then
            echo "3 Mount_${CONNECTIONTYPE}_RW_:$DIRECTORY - Unknown write error $RET_W has occured while writing test file to $DIRECTORY"
            continue
        fi

        TESTREAD=$(timeout 1s cat "$DIRECTORY"/"$TESTFILE")
        RET_R=$?
        if [[ $RET_R -eq 124 || $RET_R -eq 137 ]]; then
            echo "2 Mount_${CONNECTIONTYPE}_RW_:$DIRECTORY - Reading test from $DIRECTORY/$TESTFILE timed out"
            continue
        elif [[ $RET_R -ne 0 ]]; then
            echo "3 Mount_${CONNECTIONTYPE}_RW_:$DIRECTORY - Unknown read error $RET_R has occured while reading test file from $DIRECTORY/$TESTFILE"
            continue
        fi

        if [[ $TESTREAD -eq $RAND ]]; then
            timeout 1s rm -f "$DIRECTORY"/"$TESTFILE"
            RET_RM=$?
            if [[ $RET_RM -eq 124 || $RET_RM -eq 137 ]]; then
                echo "2 Mount_${CONNECTIONTYPE}_RW_:$DIRECTORY - Removing the test file from $DIRECTORY/$TESTFILE timed out"
                continue
            elif [[ $RET_RM -ne 0 ]]; then
                echo "2 Mount_${CONNECTIONTYPE}_RW_:$DIRECTORY - Failed to remove the test file from $DIRECTORY/$TESTFILE"
                continue
            else
                echo "0 Mount_${CONNECTIONTYPE}_RW_:$DIRECTORY - Write and read test to the $DIRECTORY mount point was successful"
                continue
            fi
        else
            echo "2 Mount_${CONNECTIONTYPE}_RW_:$DIRECTORY - Content in the test file from $DIRECTORY/$TESTFILE does not match the source input"
            continue
        fi
    done
}

while getopts "hv" opt; do
    case "$opt" in
        h)
            print_help
            ;;
        v)
            echo "$PROGNAME version: $REVISION"
            exit 0
            ;;
        \?)
            print_help
            ;;
    esac
done

check_mount_rw
exit 0
