#!/bin/bash

#######
## Simple script for an Icinga2 event command, the script tries a server reset under certain circumstances 
## Author: Sebastian Klee
## E-Mail: s.klee@timmehosting.de
## Version: 1.4
## Date: 16.12.2025
#######


while getopts "s:t:a:h:S:d:m:n:e:" opt; do
  case $opt in
    s)
      hoststate=$OPTARG
      ;;
    t)
      hoststatetype=$OPTARG
      ;;
    a)
      hostattempt=$OPTARG
      ;;
    h)
      hostname=$OPTARG
      ;;
    S)
      servernumber=$OPTARG
      ;;
    d)
      downtime=$OPTARG
      ;;
    m)
      master=$OPTARG
      ;;
    n)
      number_reset=$OPTARG
      ;;
    e)
      responsible_satellites=$OPTARG
      ;;
    *)
      echo "USAGE: $0 -s hoststate -t hoststatetype -a hostattempt -h hostname -S servernumber -d downtime -m master -n number_reset -e responsible_satellites"
      exit 3 ;;
  esac
done

if [ -z "$hoststate" ] || [ -z "$hoststatetype" ] || [ -z "$hostattempt" ] || [ -z "$hostname" ] || [ -z "$servernumber" ] || [ -z "$downtime" ] || [ -z "$master" ] || [ -z "$number_reset" ] || [ -z "$responsible_satellites" ]; then
  echo "USAGE: $0 -s hoststate -t hoststatetype -a hostattempt -h hostname -S servernumber -d downtime -m master"
  exit 3;
else
  # Try an automatic hardware reset, if the third check attempt within the soft state delivers a critical result and no downtime is set
  if [ "$hoststate" == "DOWN" ] && [ "$hoststatetype" == "SOFT" ] && [ "$hostattempt" -eq 3 ] && [ "$downtime" -eq 0 ]; then

    status1=1
    status2=1
    regex='core[0-9]'
    regex2='ex[0-9]'

    traceroute_ausgabe=$(traceroute -m 14 "$hostname")
    echo -e "### $(date) - Ausgabe \"TRACEROUTE\":\\n $traceroute_ausgabe" >> /var/log/icinga2/reset_host.log

    # If query to set the Value of the variable "status1" to "0" if the variable "traceroute_ausgabe" contains the string of the variable "regex"
    if [[ "$traceroute_ausgabe" =~ $regex ]];then
      status1=0
    fi
    # If query to set the Value of the variable "status2" to "0" if the variable "traceroute_ausgabe" contains the string of the variable "regex2"
    if [[ "$traceroute_ausgabe" =~ $regex2 ]];then
      status2=0
    fi

    # If query, whether a problem with the network is assumed or not
    if [[ $status1 -eq 0 ]] && [[ $status2 -eq 0 ]];then
      echo -e "### Ergebnis von TRACEROUTE deutet auf keine Netzwerkstoerung hin, pruefe erneut PING" >> /var/log/icinga2/reset_host.log
      ping_ausgabe=$(ping "$hostname" -w 5)
      ping_status=$?

      # Show the ping results, try to reset the server via the "Robot API" if the status code of the result is not 0(success).
      if [[ $ping_status -eq 0 ]];then
        {
        echo -e "\\n### $(date) - Server ${hostname} per PING erreichbar:"
        echo "$ping_ausgabe" | awk /transmitted/
        echo "------------------------------------------------------------------------------------"
        } >> /var/log/icinga2/reset_host.log
      else
        {
        echo -e "\\n### $(date) - Server ${hostname} weiterhin nicht per PING erreichbar:"
        echo "$ping_ausgabe" | awk /transmitted/

        # Setting up a counter for the number of resets through this script
        counter_directory=/var/log/icinga2/counter_reset_servers/servernumber_$servernumber
        counter=0

        # If the directory for the counter does not exist, create it and write the actual value for the counter to the associated log file
        if [[ ! -d "$counter_directory" ]]; then
          mkdir "$counter_directory"
          echo $counter > "$counter_directory"/"$servernumber".log
        fi

        # Assign the actual count from associated log file to the variable "counter" and increment it per one
        counter=$(cat "$counter_directory"/"$servernumber".log)
        counter=$((counter + 1))

        # Don't try a reset, if the variable "counter" has a higher value then number_reset
        if [[ $counter -le "$number_reset" ]]; then
          # Setting up a downtime for the UPTIME service check
          start_time_downtime=$(date +%s -d "+0 minute")
          end_time_downtime=$(date +%s -d "+12 minute")
          curl -k -s --netrc-file /etc/icinga2/scripts/api_u/downtime.cnf -H 'Accept: application/json' -X POST https://"${master}":5665/v1/actions/schedule-downtime -d \
          '{ "type": "Service", "filter": "host.name==\"'"$hostname"'\" && service.name==\"Uptime\"", "author": "Reset", "start_time": '"$start_time_downtime"', "end_time": '"$end_time_downtime"', "comment": "Automatischer Hardware Reset", "pretty": true }' > /dev/null 2>&1
          #
          echo -e "\\n### $(date) - Versuche automatischen Hardware-reset:"
          curl -s -k --netrc-file /etc/icinga2/scripts/api_u/api_hetz.cnf https://robot-ws.your-server.de/reset/"${servernumber}" -d type=hw
          echo -e "\\n\\n### Aktuelle Anzahl der am $(date +%d.%m.%Y) vom $(hostname -f) ausgeloesten Hardware-Resets für ${hostname}(Servernummer: ${servernumber}): ${counter}\\n"
          echo "------------------------------------------------------------------------------------"
        else
          counter=$((counter - 1))
          echo -e "\\n### $(date) - Es wird kein Hardware-reset versucht, das Skript hat heute($(date +%d.%m.%Y)) bereits ${counter} automatische Hardware-Resets fuer den Server ${hostname}(Servernummer: ${servernumber}) ausgeloest.\\n"
          echo "------------------------------------------------------------------------------------"
        fi
        # Write the new count to the log file
        echo $counter > "$counter_directory"/"$servernumber".log

        satellite_one=$(echo "$responsible_satellites" | awk -F "," '{print$1}')
        satellite_two=$(echo "$responsible_satellites" | awk -F "," '{print$2}')
        hostname=$(hostname -f)
        if [[ $hostname == "$satellite_one" ]]; then
          rsync -a "$counter_directory" root@"${satellite_two}":/var/log/icinga2/counter_reset_servers/
        elif [[ $hostname == "$satellite_two" ]]; then
          rsync -a "$counter_directory" root@"${satellite_one}":/var/log/icinga2/counter_reset_servers/
        fi
        } >> /var/log/icinga2/reset_host.log
      fi

    else
      {
      echo -e "\\n### $(date) - Host vermutlich aufgrund einer Netzwerkstoerung nicht erreichbar, automatischer Hardware-Reset wird nicht versucht\\n"
      echo "------------------------------------------------------------------------------------"
      } >> /var/log/icinga2/reset_host.log
    fi
  fi
fi
