#!/bin/bash
# Script to check if wazuh agents on monitored server are disconnected from the responcible wazuh servers.
# Author: Sebastian Klee, E-Mail: s.klee@timmehosting.de
# Version: 1.2
# Date: 14.10.2025

# Variables
# Counter for hosts that are not connected to "wazuh".
counter_disconnected=0
# Counter for hosts with a "downtime" that are not connected to "wazuh".
counter_downtime=0
# Variable "wazuh_server" receives its value (the wazuh server to be queried) from the monitoring.
wazuh_server=$1
# The Variable "monitoring_master" receives its value from the monitoring, we need the variable for an API request. The request checks for "downtimes".
monitoring_master=$2
# The variable "exceptions" receives its value from the monitoring, we use it to define exceptions for servers that our check should not take into account.
exceptions=$3
# Used only to filter the output of the API request that shows the disconnected servers
pattern="name"

# API request to retrieve an access token for the queried Wazuh server. The token is used for the subsequent API request that returns the disconnected hosts.
token_wazuh_request=$(curl -s --netrc-file /etc/icinga2/scripts/api_u/wazuh_ic2.cnf -k -X POST "https://${wazuh_server}:55000/security/user/authenticate" | jq | tr -d '" ' | awk -F ':' ' /token/ {print$2}')
wazuh_disconnected_hosts=$(curl -s -H "Authorization: Bearer $token_wazuh_request" -k -X GET "https://${wazuh_server}:55000/agents?status=disconnected&q=group!=disabled&select=name" | jq | tr -d '", ' | awk -v pat="$pattern" '$0 ~ pat {print$0}' | awk -v exc="$exceptions" -F ":" '$0 !~ exc {print$2}')

# The "for-loop" is repeated for each server in the variable "wazuh_disconnected_hosts".
for i in $wazuh_disconnected_hosts; do
  # The variable "downtime_host" is used to check if the actual server in the variable "i" has a Downtime, we determine this through an API request to the monitoring.
  downtime_host=$(curl -k -s --netrc-file /etc/icinga2/scripts/api_u/wazuh_ic2.cnf -H 'Accept: application/json' -X GET https://"${monitoring_master}":5665/v1/objects/downtimes -d \ '{ "type": "Downtime", "filter": "host.name==\"'"$i"'\"", "attrs" : ["service_name"], "pretty": true}' | grep -c '""')
  # IF-Condition: The variable "counter_disconnected" is incremented by one if the condition is met.
  # If this is not the case, the current server in the variable "i" is written to the array "discon_hosts_downtime" and the variable "counter_downtime" is incremented by one.
  if [[ downtime_host -eq 0 ]]; then
    ((counter_disconnected++))
  else
    discon_hosts_downtime[counter_downtime]=$i
    ((counter_downtime++))
  fi
done

# IF-Condition: The condition is met if the variable "counter_disconnected" ist greater than 0.
if [[ counter_disconnected -gt 0 ]]; then
  echo "Disconnected Server:"
  # Output for all servers not connected to Wazuh.
  for i in $wazuh_disconnected_hosts; do
   # IF-Condition: Used to distinguish between servers with and without a "downtime".
   if [[ ${discon_hosts_downtime[*]} =~ $i ]]; then
     echo "${i}(Downtime Monitoring)"
   else
     echo "$i"
   fi
  done
  # Script ends with exit code 2(critical).
  exit 2
fi

# If-Request: Only used if all server without a "downtime" are connected. Used to distinguish between servers with and without a "downtime".  
if [[ counter_downtime -eq 0 ]]; then
  echo "All Server are connected!"
else
  echo "All Server without a \"Downtime\" are connected!"
  echo "Servers with a \"Downtime\" that are not connected to Wazuh:"
  echo "${discon_hosts_downtime[@]}"
fi
# Script ends with exit code 0(ok).
exit 0
