#!/bin/bash

# Default threshold values.
ips_threshold_warning=20
ips_threshold_critical=40

print_help() {
    echo "usage: ${0} [OPTIONS] <jails>"
    echo "options:"
    echo -e " -c, --critical <ips count>\t\tcritical threshold values for IP count"
    echo -e " -h, --help\t\t\t\tprint this help"
    echo -e " -w, --warning <ips count>\t\twarning threshold values for IP count"
}

[[ $# -lt 1 ]] && (echo "err: <jails> argument missing"; exit 2)

while [[ $# -gt 1 ]]; do
    case "$1" in
        -c|--critical)
            ips_threshold_critical=$(/usr/bin/awk '{print +$1}' <(echo $2))
            shift 1
            ;;

        -w|--warning)
            ips_threshold_warning=$(/usr/bin/awk '{print +$1}' <(echo $2))
            shift 1
            ;;

        -h|--help)
            print_help
            exit 0
            ;;

        *)
            echo "err: failed to parse argument '$1'."
            exit 1
            ;;
    esac
    shift 1
done
jails=$1

# Format data.
output=''
perf=''

ips_scale=";${ips_threshold_warning};${ips_threshold_critical};0;100"

# Is fail2ban service active.
if /bin/systemctl is-active fail2ban.service 1>/dev/null 2>&1; then
    output+="OK: fail2ban service is active\n"
else
    output+="NOK: fail2ban is inactive\n"
fi

# Is fail2ban running.
if sudo /usr/bin/fail2ban-client ping 1>/dev/null 2>&1; then
    output+="OK: fail2ban is running\n"
    fail2ban_is_running=true
else
    output+="NOK: fail2ban is not running\n"
    fail2ban_is_running=false
fi

all_jail_stats=$(sudo /usr/bin/fail2ban-client banned | tr "'" '"' | python3 -c "import collections, json, sys; banned=json.load(sys.stdin); print('\n'.join([f'{name},{len(ips)}' for jails in banned for name, ips in jails.items()]))")

total_banned_ips=0
# IP address banned count for expected jails.
for jail in ${jails//,/ }; do
    if jail_stats=$(grep "$jail" <(echo "$all_jail_stats")); then
        jail_name=$(/usr/bin/awk -F ',' '{print $1}' <(echo $jail_stats))
        if [[ "$jail_name" == "$jail" ]]; then
            jail_ips=$(/usr/bin/awk -F ',' '{print +$2}' <(echo $jail_stats))

            status='OK'
            [[ ${jail_ips} -ge $ips_threshold_warning ]] && status='WARNING'
            [[ ${jail_ips} -ge $ips_threshold_critical ]] && status='CRITICAL'
            output+="${status}: ${jail} jail hold ${jail_ips} IP addresses\n"
	   total_banned_ips=$(( $total_banned_ips + $jail_ips ))

            perf+="${jail_name}=${jail_ips}${ips_scale} "
            continue
        fi
    fi
    output+="NOK: ${jail} jail is missing\n"
done

output+="INFO: fail2ban ban ${total_banned_ips} IP addresses"
perf+="total=${total_banned_ips}${ips_scale} "

# Nagios OK status.
exit_code=0
# Nagios WARNING status.
grep --quiet 'WARNING:' <(echo $output) && exit_code=1
# Nagios CRITICAL status.
grep --quiet 'NOK:\|CRITICAL:' <(echo $output) && exit_code=2

# Plugin output.
echo "${output%'\n'}|${perf%' '}"
exit $exit_code
