#!/bin/bash

#######
## Description: Plugin checks if the docker containers on a KVM system are running, also checks RAM an CPU usage.
## Author: Sebastian Klee
## E-Mail: s.klee@timmehosting.de
## Version: 1.1
## Date: 06.09.2023
## Note: Script uses the check_docker_plugin(https://github.com/timdaman/check_docker)
#######

# Variable to check if docker is installed
service_bin="/usr/bin/docker"

# The script will be terminated with status code 0, if the file from the "service_bin" variable does not exist.
if [[ ! -f $service_bin ]]; then
    echo "Docker ist auf dem Server nicht installiert"
    exit 0
fi

# The number of existing containers, regardless of whether they are running or not, is passed to the variable "docker_container_sum".
docker_container_sum=$(docker ps -a -q | wc -l)

# The script will be terminated with status code 0, if no docker container exist.
if [[ $docker_container_sum == 0 ]]; then
    echo "Derzeit existiert kein Docker Container auf dem Server"
    exit 0
fi

# The variable "date_test" gets the current time, format HHMM
date_test=$(date +%-H%M)

# Output of the Docker command is written to the array "gpu_mem_output", the script will need the information later.
mapfile -t cpu_mem_output < <( docker stats --no-stream --format "{{.CPUPerc}}{{.MemPerc}}" )
# The variable "index_array" will be used to address the elements of the array later in the script 
index_array=0

# The for-loop is repeated for each existing container
for i in $(docker ps -a --format "{{.Names}}"); do
      # Condition for the if below, it gets the Value from the Monitoring for more flexibility
      date_cond=$1
      # The if checks if the name of the container contains 'autoinstaller' and if the current time is before 02:00,
      # it serves to avoid criticals for containers that are shut down for backups.
      if [[ $i =~ 'autoinstaller' && $date_test -lt $date_cond ]]; then
          echo "Checks des Container \"${i}\" wird ausgesetzt, Zeitraum der Container Backups erreicht"
      else
          # Determining if the container is running. The variable status receives the status code(0, 1 or 2) of the previous command(.../check_docker --conne...)
          output=$(/usr/local/lib/nagios/plugins/check_docker --connection /var/run/docker.sock --containers "$i" --uptime 300:30)
          status=$?

          # The $4 variable contains exceptions for Docker containers this check should ignore, "$4" gets it's value from our monitoring.
          # We need this "if" for containers where it ist correct that they are not running.
          if [[ $output =~ $4 ]]; then
              status=0
          else
             # Shortened Output of the "check_docker" command
             echo "$output" | cut -d '|' -f 1

             # The variables "cpu_stat" and "mem_stat" receive an element(line) from the output of the array "cpu_mem_output", the output is shortened with Cut. 
             cpu_stat=$(echo "${cpu_mem_output[$index_array]}" | cut -d '%' -f 1)
             mem_stat=$(echo "${cpu_mem_output[$index_array]}" | cut -d '%' -f 2)


             # The value of the "index_array" variable is incremented by one, in order to work with the next element of the array in the next loop iteration.
             index_array=$((index_array + 1))

             # Current value for the CPU and RAM utilization without decimal places, for the if-condition below. 
             cpu_stat_integer=$(echo "${cpu_stat}" | cut -d '.' -f 1)
             mem_stat_integer=$(echo "${mem_stat}" | cut -d '.' -f 1)

             # Conditions for the if below, it gets the Values from the Monitoring for more flexibility
             warn_cond=$2

             # The if is used to decide whether the determined CPU and RAM utilization has exceeded certain values. If this is the case, the "warn" counter is increased by one
             if [[ $cpu_stat_integer -gt $warn_cond || $mem_stat_integer -gt $warn_cond ]]; then
                 warn=$((warn + 1))
                 echo "WARNING: RAM und/oder haben eine höhere Auslastung erreicht! | CPU: ${cpu_stat}% MEM: ${mem_stat}%"
             else
                 echo "OK: RAM und CPU Auslastung im grünen Bereich | CPU: ${cpu_stat}% MEM: ${mem_stat}%"
             fi

          fi

          # This if query checks the value of the variable "status", depending on the value, the counter crit and warn are increased by one.
	  if [[ $status == 2 ]]; then
              crit=$((crit + 1))
          elif [[ $status == 1 ]]; then
              warn=$((warn + 1))
          fi

      fi

# Formatting for the script output.
echo " "

done

# This if determines what status code the script exits with if it hasn't already happened for other reasons (e.g. no Docker or containers on the server).
if [[ $crit -gt 0 ]]; then
    exit 2
elif [[ $warn -gt 0 ]]; then
    exit 1
else
    exit 0
fi

