From 092c1561828194d106b016aa8419f3d1830c9d81 Mon Sep 17 00:00:00 2001
From: "Hahn Axel (hahn)" <axel.hahn@iml.unibe.ch>
Date: Mon, 10 Aug 2020 09:06:15 +0200
Subject: [PATCH] add check_snmp_synology

---
 .gitignore          |   3 +-
 check_snmp_synology | 280 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 281 insertions(+), 2 deletions(-)
 create mode 100755 check_snmp_synology

diff --git a/.gitignore b/.gitignore
index 754c640..a3a695e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
 check_smart.pl
 paramtest
 check_snmp_syno.sh
-check_snmp_synology
-check-cpu.sh
\ No newline at end of file
+check-cpu.sh
diff --git a/check_snmp_synology b/check_snmp_synology
new file mode 100755
index 0000000..35a925b
--- /dev/null
+++ b/check_snmp_synology
@@ -0,0 +1,280 @@
+#!/bin/bash
+# check_snmp_synology for nagios version 1.1
+# 30.04.2013  Nicolas Ordonez, Switzerland
+# 08.08.2020  Axel Hahn: add update, community string
+#---------------------------------------------------
+# this plugin check the health of your Synology NAS
+# - System status (Power, Fans)
+# - Disks status 
+# - RAID status
+# - available updates
+#
+# Tested with DSM 6.2
+#---------------------------------------------------
+# see docs:
+# https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_DiskStation_MIB_Guide.pdf
+#---------------------------------------------------
+
+. `dirname $0`/inc_pluginfunctions
+
+# --- basic vars
+SNMPCOMMUNITY="public"
+SNMPVERSION="2c"
+SNMPWALK=$(which snmpwalk)
+SNMPGET=$(which snmpget)
+
+HOSTNAME=""
+option_found=0
+healthString=""
+verbose="no"
+out=""
+
+# --- OID declarations
+OID_syno="1.3.6.1.4.1.6574"
+OID_model="${OID_syno}.1.5.1.0"
+OID_serialNumber="${OID_syno}.1.5.2.0"
+OID_DSMVersion="${OID_syno}.1.5.3.0"
+OID_DSMUpdateAvailable="${OID_syno}.1.5.4.0"
+OID_systemStatus="${OID_syno}.1.1.0"
+OID_powerStatus="${OID_syno}.1.3.0"
+OID_systemFanStatus="${OID_syno}.1.4.1.0"
+OID_CPUFanStatus="${OID_syno}.1.4.2.0"
+OID_temp="${OID_syno}.1.2.0"
+
+OID_disk=""
+OID_diskID="${OID_syno}.2.1.1.2"
+OID_diskModel="${OID_syno}.2.1.1.3"
+OID_diskStatus="${OID_syno}.2.1.1.5"
+OID_diskTemp="${OID_syno}.2.1.1.6"
+
+OID_RAID=""
+OID_RAIDName="${OID_syno}.3.1.1.2"
+OID_RAIDStatus="${OID_syno}.3.1.1.3"
+
+OID_RAIDFree="${OID_syno}.3.1.1.4"
+OID_RAIDSize="${OID_syno}.3.1.1.5"
+
+
+# --- status arrays to show results
+#                0     1          2             3               4                      5
+aStatusDual=(    "???" Normal     Failed)
+aStatusUpgrade=( "???" Yes        "Up to date"  Connecting      Disconnected           Others)
+aStatusDisk=(    "???" Normal     Initialized   NotInitialized  SystemPartitionFailed  Crashed)
+aStatusRaid=(    "???" Normal     Repairing     Migrating       Expanding              Deleting Creating RaidSyncing RaidParityChecking RaidAssembling Canceling Degrade Crashed DataScrubbing RaidDeploying RaidUnDeploying RaidMountCache RaidExpandingUnfinishedSHR RaidConvertSHRToPool RaidMigrateSHR1ToSHR2 RaidUnknownStatus)
+
+aStatusSystem=$aStatusDual
+aStatusPower=$aStatusDual
+aStatusFan=$aStatusDual
+
+
+#---------------------------------------------------
+# FUNCTIONS
+#---------------------------------------------------
+
+# --- write verbose text
+_wd()
+{
+    if [ "$verbose" = "yes" ] ; then 
+        out="${out}$*
+" ; fi
+}
+
+# --- get a value from SNMP output data
+# param  string  mib string
+_get(){
+    echo "$syno" | grep "${1} " | cut -d "=" -f2 | cut -f 2- -d " "
+}
+
+# --- show usage
+usage()
+{
+        ph.abort "usage: ./check_snmp_synology -h hostname [-C communitystring] [-v verbose]"
+}
+
+#---------------------------------------------------
+# MAIN
+#---------------------------------------------------
+
+while getopts h:v OPTNAME; do
+        case "$OPTNAME" in
+
+        h)
+                HOSTNAME="$OPTARG"
+                option_found=1
+                ;;
+		C)
+			    SNMPCOMMUNITY="$OPTARG"
+			    ;;
+        v)
+                verbose="yes"
+                ;;
+        *)
+                usage
+                ;;
+        esac
+done
+
+if [ "$option_found" = "0" ] || [ "$HOSTNAME" = "" ] ; then
+    usage
+    # remark: script aborts ...
+fi
+
+
+# --- read raid and disks to get its single OIDs
+nbDisk=`$SNMPWALK -OQne -t 10 -v $SNMPVERSION -c $SNMPCOMMUNITY $HOSTNAME $OID_diskID   2> /dev/null | wc -l `
+nbRAID=`$SNMPWALK -OQne -t 10 -v $SNMPVERSION -c $SNMPCOMMUNITY $HOSTNAME $OID_RAIDName 2> /dev/null | wc -l`
+
+for i in `seq 1 $nbDisk`;
+do
+    OID_disk="$OID_disk $OID_diskID.$(($i-1)) $OID_diskModel.$(($i-1)) $OID_diskStatus.$(($i-1)) $OID_diskTemp.$(($i-1)) " 
+done
+for i in `seq 1 $nbRAID`;
+do
+    OID_RAID="$OID_RAID $OID_RAIDName.$(($i-1)) $OID_RAIDStatus.$(($i-1)) $OID_RAIDSize.$(($i-1)) $OID_RAIDFree.$(($i-1))" 
+done
+
+# --- SNPGET to all wanted oids
+syno=`$SNMPGET -OQne -t 10 -v $SNMPVERSION -c $SNMPCOMMUNITY $HOSTNAME $OID_model $OID_serialNumber $OID_DSMVersion $OID_DSMUpdateAvailable $OID_systemStatus $OID_powerStatus $OID_systemFanStatus $OID_CPUFanStatus $OID_temp $OID_disk $OID_RAID 2> /dev/null | sed 's/^[ \t]*//;s/[ \t]*$//'`
+
+if [ "$?" != "0" ] ; then
+    ph.abort "Problem with SNMP request"
+fi
+
+_wd ""
+
+# --- check fetched data
+model=$(_get $OID_model)
+_wd "Synology model:    $model"
+
+serialNumber=$(_get $OID_serialNumber)
+_wd "Synology s/n:      $serialNumber"
+
+DSMVersion=$(_get $OID_DSMVersion)
+_wd "DSM Version:       $DSMVersion"
+
+healthString="Synology $model (s/n:$serialNumber, $DSMVersion)"
+
+RAIDName=$(_get $OID_RAIDName)
+RAIDStatus=$(_get $OID_RAIDStatus)
+
+
+# --- check update
+typeset -i DSMupdate=$(_get $OID_DSMUpdateAvailable)
+_wd "Update available:  ${aStatusUpgrade[$DSMupdate]} ($DSMupdate)"
+if [ $DSMupdate -eq 1 ] ; then
+    ph.setStatus "warning"
+    healthString="$healthString, Update available"
+fi
+_wd ""
+
+
+# --- Check system status
+systemStatus=$(_get $OID_systemStatus)
+
+if [ $systemStatus != "1" ] ; then
+    if [ "$systemStatus" = "2" ] ; then      systemStatus="Failed";          fi
+    ph.setStatus "critical"
+    healthString="$healthString, System status: $systemStatus "
+else
+    systemStatus="Normal"
+fi
+_wd "System Status:     $systemStatus"
+
+
+# --- Check power status
+powerStatus=$(_get $OID_powerStatus)
+
+if [ $powerStatus != "1" ] ; then
+    if [ "$powerStatus" = "2" ] ; then       powerStatus="Failed";           fi
+    ph.setStatus "critical"
+    healthString="$healthString, Power status: $powerStatus "
+else
+    powerStatus="Normal"
+fi
+_wd "Power Status:      $powerStatus"
+
+
+# --- Check system fan status
+systemFanStatus=$(_get $OID_systemFanStatus)
+if [ $systemFanStatus != "1" ] ; then
+    if [ "$systemFanStatus" = "2" ] ; then   systemFanStatus="Failed";               fi
+    ph.setStatus "critical"
+    healthString="$healthString, System fan status: $systemFanStatus "
+else
+    systemFanStatus="Normal"
+fi
+_wd "System Fan Status: $systemFanStatus"
+
+
+# --- Check CPU fan status
+CPUFanStatus=$(_get $OID_CPUFanStatus)
+if [ $CPUFanStatus != "1" ] ; then
+    if [ "$CPUFanStatus" = "2" ] ; then      CPUFanStatus="Failed";          fi
+    ph.setStatus "critical"
+    healthString="$healthString, CPU fan status: $CPUFanStatus "
+else
+    CPUFanStatus="Normal"
+fi
+_wd "CPU Fan Status:    $CPUFanStatus"
+
+
+# --- Show temperature
+DeviceTemperature=$(_get $OID_temp)
+# if [ $DeviceTemperature ...  ] ; then
+#     ph.setStatus "critical"
+#     healthString="$healthString, CPU fan status: $CPUFanStatus °C"
+# else
+#     CPUFanStatus="Normal"
+# fi
+_wd "NAS temperature:   $DeviceTemperature °C"
+
+
+# --- Check all disk status
+_wd ""
+_wd "Number of disks:   $nbDisk"
+for i in `seq 1 $nbDisk`;
+do
+    diskID[$i]=$(_get $OID_diskID.$(($i-1)))
+    diskModel[$i]=$(_get $OID_diskModel.$(($i-1)))
+    diskTemp[$i]=$(_get $OID_diskTemp.$(($i-1)))
+    idiskStatus=$(_get $OID_diskStatus.$(($i-1)))
+
+    diskStatus[$i]=${aStatusDisk[$idiskStatus]}
+   
+    if [ ${idiskStatus} != "1" ] ; then
+        ph.setStatus "critical"
+        healthString="$healthString, problem with ${diskID[$i]} (model:${diskModel[$i]}) status:${diskStatus[$i]} temperature:${diskTemp[$i]} C "
+    fi
+
+    _wd "${diskID[$i]} (model:${diskModel[$i]}) status: ${diskStatus[$i]} ($idiskStatus) temperature: ${diskTemp[$i]} °C"
+done
+
+
+# --- Check all RAID volume status
+_wd ""
+_wd "Number of RAID volume: $nbRAID"
+for i in `seq 1 $nbRAID`;
+do
+    RAIDName[$i]=$(_get $OID_RAIDName.$(($i-1)))
+    iRAIDStatus=$(_get $OID_RAIDStatus.$(($i-1)))
+
+    # size in integer GB
+    iRAIDSize=$(( $(_get $OID_RAIDSize.$(($i-1))) / 1024/1024/1024 ))
+    iRAIDFree=$(( $(_get $OID_RAIDFree.$(($i-1))) / 1024/1024/1024 ))
+    iFree=$(( iRAIDFree*100/$iRAIDSize ))
+
+    RAIDStatus[$i]=${aStatusRaid[${iRAIDStatus}]}
+
+    if [ $iRAIDStatus != "1" ] ; then
+        ph.setStatus "critical"
+        healthString="$healthString, RAID status: ($RAIDName ): $RAIDStatus[$i] "
+    fi
+    _wd "${RAIDName[$i]} status: ${RAIDStatus[$i]} ($iRAIDStatus) - size $iRAIDSize GB, free $iRAIDFree GB (${iFree}%)"
+done
+
+
+# --- output status
+ph.status "$healthString"
+echo "$out"
+
+ph.exit
\ No newline at end of file
-- 
GitLab