| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 | #!/bin/bash############################################################### check_omada## Version 1.0## Ein Plugin fuer Icinga / Nagios# zur ueberwachung und Auswertung eines# Omada-Controllers ab Version 5## Urheber: Daniel Wenzel# Kontakt: daniel@klenzel.de### Abhaengigkeiten:# - 'jq'# - 'curl'## Beispiel fuer Debian: apt-get install jq curl## ---------------------------------------------## 1.0 - Changelog:## 20230312# - Initiale Version################################################################Funktionenfunction showUsage {  echo "  Benutzung: $0 [Parameter]  -H  Hostname / IP-Adresse des Omada Controllers  -P  Port (Standard = 443) des Omada-Controllers  -u  Benutzername  -p  Passwort    -s  Angabe der Seiten-ID (nicht Name!)  -m  Modul      'Count-EAPUsers'    => Zeigt auf dem Accesspoint angemeldete Nutzer an	  'Get-DeviceLoad'    => Gibt CPU-Auslastung aus	  'Get-DeviceMem'     => Gibt Arbeitsspeicher-Auslastung aus	  'Get-PortStat'      => Zeigt Traffic-Statistiken eines Ports      'Show-Updates'      => Zeigt, ob fuer den Unifi-Controller Aktualisierungen verfuegbar sind	  'Show-Connection'   => Prueft, ob ein Geraet am Omada-Controller angemeldet ist	  'Show-PoEStatus'    => Zeigt die verbleibende PoE-Kapazitaet an  -i  (nur bei Get-PortStat notwendig) Angabe des abzufragenden Ports  -d  Angabe des abzufragenden Geraets  -w  Angabe, unter welchem Wert der Status 'Warning' ausgegeben werden soll      'Count-Users'      => Warnung, wenn Anzahl Nutzer kleiner als der definierte Warning-Wert                            Eingabe im Format: 'n'      'Active-Alarms'    => Ab dieser Anzahl von Alarmmeldungen wird der Status 'Warning' ausgeben                            Eingabe im Format: 'n'      'Offline-APs'      => Ab dieser Anzahl nicht verfuegbarer APs wird der Status 'Warning' ausgeben                            Eingabe im Format: 'n'      'Has-Updates'      => Ab dieser Anzahl von gefundenen Upgrades wird der Status 'Warning' ausgeben                            Eingabe im Format: 'n'      'Not-Adopted'      => Ab dieser Anzahl nicht zugewiesener Accesspoints wird der Status 'Warning' ausgeben                            Eingabe im Format: 'n'      'Get-DeviceLoad'   => Ist die Load der letzten Minute größer als der angegebene Wert, wird der Status 'Warning' ausgeben                            Eingabe im Format: 'n.nn'      'Get-DeviceMem'    => Ist die Auslastung des Arbeitsspeichers höher als der angegebene Wert, wird der Status 'Warning' ausgeben                            Eingabe im Format: 'nn' (z.B. '80' fuer 80% Auslastung)      'Get-DeviceUsers'  => Gibt die maximale Anzahl der mit einem AP verbundenen Nutzer an, ab der der Status 'Warning' ausgegeben wird                            Eingabe im Format: 'n'      'Get-DeviceGuests' => Gibt die maximale Anzahl der mit einem AP verbundenen Gaeste an, ab der der Status 'Warning' ausgegeben wird                            Eingabe im Format: 'n'      'Show-DevLastSeen' => Gibt die vergangenen Sekunden der letzten Sichtung an, ab die der Status 'Warning' ausgegeben wird  -c  Angabe, unter welchem Wert der Status 'Critical' ausgegeben werden soll      Erlaeuterungen analog zu 'Warning'  "}#Paramter verarbeitenwhile [ "$1" != "" ]; do  case "$1" in    -H) shift; strHost="$1";;    -P) shift; intPort="$1";;    -u) shift; strUsername="$1";;    -p) shift; strPassword="$1";;    -m) shift; strModus="$1";;	-i) shift; strInterface="$1";;    -d) shift; strDevice="$1";;    -s) shift; strSeite="$1";;    -w) shift; intWarning="$1";;    -c) shift; intCritical="$1";;    *) showUsage; exit 3;;  esac  shiftdoneif [ -z $strHost ] || [ -z $strUsername ] || [ -z $strPassword ] || [ -z $strModus ] || [ -z $strDevice ] || [ -z $strSeite ]; then  showUsage  exit 1fiif ( [ "$strModus" == "Get-PortStat" ] ) && ( [ -z $strInterface ] ) ; then  showUsage  exit 1fiif ( [ "$strModus" == "Get-DeviceLoad" ] || [ "$strModus" == "Get-DeviceMem" ] || [ "$strModus" == "Count-EAPUsers" ] || [ "$strModus" == "Show-PoEStatus" ] ) && ( [ -z $intWarning ] || [ -z $intCritical ] ) ; then  showUsage  exit 1fistrDevice=$(echo ${strDevice^^})if [ -z $intPort ] ; then  intPort=443fi#################strJQBinary=$(which jq)if [ $? -ne 0 ] ; then  echo "Bitte den JSON-Prozessor ${strJQBinary} installieren"  exit 3fistrCurlBinary=$(which curl)if [ $? -ne 0 ] ; then  echo "Bitte das Paket curl installieren"  exit 3fi#MetaintRandom=$(( $RANDOM % 100000 ))strBaseURL="https://${strHost}:${intPort}"strCookieFile="/tmp/omada_${intRandom}.cookie"strCurlCommand="${strCurlBinary} --silent --cookie ${strCookieFile} --cookie-jar ${strCookieFile} --insecure"#strLogOutAndCleanUp="${strCurlCommand} $strBaseURL/logout > /dev/null 2>&1 ; rm -f ${strCookieFile}"strLogOutAndCleanUp="rm -f ${strCookieFile}"#Anmelden am ControllerintControllerID=$(${strCurlCommand} "${strBaseURL}/api/info" | jq -r .result.omadacId)intToken=$(${strCurlCommand} -X POST -H "Content-Type: application/json" "${strBaseURL}/${intControllerID}/api/v2/login" -d '{"username": "'"${strUsername}"'", "password": "'"${strPassword}"'"}' | ${strJQBinary} -r .result.token)strLoginStatus=$(${strCurlCommand} -X GET -H "Content-Type: application/json" -H "Csrf-Token: ${intToken}" "${strBaseURL}/${intControllerID}/api/v2/loginStatus" | ${strJQBinary} -r .msg)if [ "$strLoginStatus" != "Success." ] ; then  echo "Unknown: Anmeldung am Omada-Controller fehlgeschlagen"  eval ${strLogOutAndCleanUp}  exit 2fi########## Modi Beginn ########### [Count-EAPUsers] Zeigt auf dem Accesspoint angemeldete Nutzer an# -------------------------------------------if [ "$strModus" == "Count-EAPUsers" ] ; then  intAngemeldeteNutzer=$(${strCurlCommand} -X GET -H "Content-Type: application/json" -H "Csrf-Token: ${intToken}" "${strBaseURL}/${intControllerID}/api/v2/sites/${strSeite}/devices" | jq '.result | map(. | select(.name=="'${strDevice}'")) | . [] .clientNum')  if [ $intAngemeldeteNutzer -lt $intCritical ] ; then    echo "Critical: Angemeldete Nutzer (${intAngemeldeteNutzer}) kleiner als die minimale Menge (${intCritical}) | ActiveUsers=${intAngemeldeteNutzer}"    eval ${strLogOutAndCleanUp}    exit 2  elif [ $intAngemeldeteNutzer -lt $intWarning ] ; then    echo "Warning: Angemeldete Nutzer (${intAngemeldeteNutzer}) kleiner als die minimale Menge (${intWarning}) | ActiveUsers=${intAngemeldeteNutzer}"    eval ${strLogOutAndCleanUp}    exit 1  else    echo "OK: Es sind ${intAngemeldeteNutzer} Nutzer/Geraete am Accesspoint angemeldet | ActiveUsers=${intAngemeldeteNutzer}"    eval ${strLogOutAndCleanUp}    exit 0  fifi# [Show-PoEStatus] Zeigt die verbleibende PoE-Kapazitaet an# -------------------------------------------if [ "$strModus" == "Show-PoEStatus" ] ; then  intPoERemaining=$(${strCurlCommand} -X GET -H "Content-Type: application/json" -H "Csrf-Token: ${intToken}" "${strBaseURL}/${intControllerID}/api/v2/sites/${strSeite}/devices" | jq '.result | map(. | select(.name=="'${strDevice}'")) | . [] .poeRemain')  intPoERemaining=$(echo $intPoERemaining | cut -d. -f1)  if [ -z "$intPoERemaining" ] || [ "$intPoERemaining" == "null" ]; then    echo "UNKNOWN: Entweder kein PoE-faehiges Geraet oder unbekannter Fehler"    eval ${strLogOutAndCleanUp}    exit 3  fi    if [ $intPoERemaining -lt $intCritical ] ; then    echo "Critical: Es stehen nur noch ${intPoERemaining} Watt zur Verfuegung | PoERemaining=${intPoERemaining}"    eval ${strLogOutAndCleanUp}    exit 2  elif [ $intPoERemaining -lt $intWarning ] ; then    echo "Warning: Es stehen nur noch ${intPoERemaining} Watt zur Verfuegung | PoERemaining=${intPoERemaining}"    eval ${strLogOutAndCleanUp}    exit 1  else    echo "OK: Es stehen noch ${intPoERemaining} Watt zur Verfuegung | PoERemaining=${intPoERemaining}"    eval ${strLogOutAndCleanUp}    exit 0  fifi# [Show-Connection] Prueft, ob ein Geraet am Omada-Controller angemeldet ist# -------------------------------------------if [ "$strModus" == "Show-Connection" ] ; then  intDeviceStatus=$(${strCurlCommand} -X GET -H "Content-Type: application/json" -H "Csrf-Token: ${intToken}" "${strBaseURL}/${intControllerID}/api/v2/sites/${strSeite}/devices" | jq '.result | map(. | select(.name=="'${strDevice}'")) | . [] .status')  if [ $intDeviceStatus -eq 14 ] ; then    echo "OK: Geraet ist mit dem Omada-Controller verbunden"    eval ${strLogOutAndCleanUp}    exit 0  elif [ $intDeviceStatus -eq 0 ] ; then    echo "Critical: Keine Verbindung vom Omada-Controller zum Geraet"    eval ${strLogOutAndCleanUp}    exit 2  else    echo "Warning: Geraet verbunden, aber in einem anderen Status (Status ${intDeviceStatus})"    eval ${strLogOutAndCleanUp}    exit 1  fifi# [Show-Updates] Zeigt, ob fuer den das Geraet Aktualisierungen verfuegbar sind# -------------------------------------------if [ "$strModus" == "Show-Updates" ] ; then  strDeviceMAC=$(${strCurlCommand} -X GET -H "Content-Type: application/json" -H "Csrf-Token: ${intToken}" "${strBaseURL}/${intControllerID}/api/v2/devices?searchKey=${strDevice}" | ${strJQBinary} -r .result.devices[0].mac)  strFirmwares=$(${strCurlCommand} -X GET -H "Content-Type: application/json" -H "Csrf-Token: ${intToken}" "${strBaseURL}/${intControllerID}/api/v2/sites/${strSeite}/devices/${strDeviceMAC}/firmware" | jq '.result.curFwVer + ";" +  .result.lastFwVer' | tr -d "\"")    strFirmwareCur=$(echo $strFirmwares | cut -d ";" -f 1)  strFirmwareAvail=$(echo $strFirmwares | cut -d ";" -f 2)  if [ -z "$strFirmwareAvail" ] ; then    echo "OK: Firmware ist auf dem neusten Stand."    eval ${strLogOutAndCleanUp}    exit 0  fi  if [[ "$strFirmwareCur" != "$strFirmwareAvail" ]] ; then    echo "Warning: Geraeteaktualisierung vorhanden (Neue Firmware: ${strFirmwareAvail})"    eval ${strLogOutAndCleanUp}    exit 1  else    echo "OK: Firmware ist auf dem neusten Stand (Version ${strFirmwareCur})"    eval ${strLogOutAndCleanUp}    exit 0  fi  fi# [Get-DeviceLoad] Zeigt die CPU-Auslastung eines Geraets an# -------------------------------------------if [ "$strModus" == "Get-DeviceLoad" ] ; then  intDeviceUtil=$(${strCurlCommand} -X GET -H "Content-Type: application/json" -H "Csrf-Token: ${intToken}" "${strBaseURL}/${intControllerID}/api/v2/sites/${strSeite}/devices" | jq '.result | map(. | select(.name=="'${strDevice}'")) | . [] .cpuUtil')  intDeviceUtil=$(echo $intDeviceUtil | cut -d. -f1)    if [ $intDeviceUtil -gt $intCritical ] ; then    echo "Critical: CPU-Auslastung des Geraets '${strDevice}' zu hoch (${intDeviceUtil}% > ${intCritical}%) | APLoad=${intDeviceUtil}%"    eval ${strLogOutAndCleanUp}    exit 2  elif [ $intDeviceUtil -gt $intWarning ] ; then    echo "Warning: CPU-Auslastung des Geraets '${strDevice}' zu hoch (${intDeviceUtil}% > ${intWarning}%) | APLoad=${intDeviceUtil}%"    eval ${strLogOutAndCleanUp}    exit 1  else    echo "OK: CPU-Auslastung des Geraets '${strDevice}' in Ordnung (${intDeviceUtil}%) | APLoad=${intDeviceUtil}%"    eval ${strLogOutAndCleanUp}    exit 0  fifi# [Get-DeviceMem] Zeigt die RAM-Belegung eines Geraets an# -------------------------------------------if [ "$strModus" == "Get-DeviceMem" ] ; then  intDeviceMem=$(${strCurlCommand} -X GET -H "Content-Type: application/json" -H "Csrf-Token: ${intToken}" "${strBaseURL}/${intControllerID}/api/v2/sites/${strSeite}/devices" | jq '.result | map(. | select(.name=="'${strDevice}'")) | . [] .memUtil')  intDeviceMem=$(echo $intDeviceMem | cut -d. -f1)    if [ $intDeviceMem -gt $intCritical ] ; then    echo "Critical: Speicher-Auslastung des Geraets '${strDevice}' zu hoch (${intDeviceMem}% > ${intCritical}%) | APMem=${intDeviceMem}%"    eval ${strLogOutAndCleanUp}    exit 2  elif [ $intDeviceMem -gt $intWarning ] ; then    echo "Warning: Speicher-Auslastung des Geraets '${strDevice}' zu hoch (${intDeviceMem}% > ${intWarning}%) | APMem=${intDeviceMem}%"    eval ${strLogOutAndCleanUp}    exit 1  else    echo "OK: Speicher-Auslastung des Geraets '${strDevice}' in Ordnung (${intDeviceMem}%) | APMem=${intDeviceMem}%"    eval ${strLogOutAndCleanUp}    exit 0  fi  fi# [Get-PortStat] Zeigt Statistiken eines Switchports an# -------------------------------------------if [ "$strModus" == "Get-PortStat" ] ; then  intTXRate=$(${strCurlCommand} -X GET -H "Content-Type: application/json" -H "Csrf-Token: ${intToken}" "${strBaseURL}/${intControllerID}/api/v2/sites/${strSeite}/insight/switch/port/overview?currentPage=1¤tPageSize=100&searchKey=${strDevice}" | ${strJQBinary} '.result.data | map(. | select(.port=='${strInterface}')) | .[] .txRate')  intRXRate=$(${strCurlCommand} -X GET -H "Content-Type: application/json" -H "Csrf-Token: ${intToken}" "${strBaseURL}/${intControllerID}/api/v2/sites/${strSeite}/insight/switch/port/overview?currentPage=1¤tPageSize=100&searchKey=${strDevice}" | ${strJQBinary} '.result.data | map(. | select(.port=='${strInterface}')) | .[] .rxRate')  echo "OK: Switchport-Statistiken gefunden (RX: ${intRXRate} TX:  ${intTXRate}) | SwitchPort${strInterface}TX=${intTXRate}b SwitchPort${strInterface}RX=${intRXRate}b"  eval ${strLogOutAndCleanUp}  exit 0fi#es wurde kein passender Modus gefundenecho "Unkown: Ungueltige Angabe des Moduls"eval ${strLogOutAndCleanUp}exit 3########## Modi Ende ##########
 |