From be54eddc3c5154d2bf4d2734c100953fd1b4af61 Mon Sep 17 00:00:00 2001
From: "Hahn Axel (hahn)" <axel.hahn@unibe.ch>
Date: Fri, 5 May 2023 12:34:37 +0200
Subject: [PATCH] snmp_data: source shared func, snmpv3; add synoio

---
 check_snmp_data | 142 +++++++++++++++++++++++++++++++-----------------
 1 file changed, 91 insertions(+), 51 deletions(-)

diff --git a/check_snmp_data b/check_snmp_data
index 7609dfb..99cf4dc 100755
--- a/check_snmp_data
+++ b/check_snmp_data
@@ -26,37 +26,47 @@
 # DATA:load:data:load5:1.3.6.1.4.1.2021.10.1.5.2:
 # DATA:load:data:load15:1.3.6.1.4.1.2021.10.1.5.3:
 #
-# DATA:netio:label:Network IO (experimental)
+# DATA:mem:label:Memory status
+# DATA:mem:data:memTotalSwap:1.3.6.1.4.1.2021.4.3.0:
+# DATA:mem:data:memAvailSwap:1.3.6.1.4.1.2021.4.4.0:
+# DATA:mem:data:memTotalReal:1.3.6.1.4.1.2021.4.5.0:
+# DATA:mem:data:memAvailReal:1.3.6.1.4.1.2021.4.6.0:
+# DATA:mem:data:memTotalFree:1.3.6.1.4.1.2021.4.11.0:
+# DATA:mem:data:memShared:1.3.6.1.4.1.2021.4.13.0:
+# DATA:mem:data:memBuffer:1.3.6.1.4.1.2021.4.14.0:
+# DATA:mem:data:memCached:1.3.6.1.4.1.2021.4.15.0:
+#
+# DATA:netio:label:Network IO
 # DATA:netio:data:in:1.3.6.1.2.1.4.3.0:
 # DATA:netio:data:out:1.3.6.1.2.1.4.10.0:
 #    
-# DATA:synotemp:label:Synology NAS temperature
-# DATA:synotemp:data:temp:1.3.6.1.4.1.6574.1.2.0:°C
-#
-# DATA:disc:label:Disc usage
+# DATA:disc:label:Synology Disc usage
 # DATA:disc:data:disc-free:1.3.6.1.4.1.6574.3.1.1.2::1.3.6.1.4.1.6574.3.1.1.4
 # DATA:disc:data:disc-space:1.3.6.1.4.1.6574.3.1.1.2::1.3.6.1.4.1.6574.3.1.1.5
 #
+# DATA:synotemp:label:Synology NAS temperature
+# DATA:synotemp:data:temp:1.3.6.1.4.1.6574.1.2.0:°C
+#
+# DATA:synoio:label:Synology Space IO
+# DATA:synoio:data:syno-io-read:1.3.6.1.4.1.6574.102.1.1.12.1
+# DATA:synoio:data:syno-io-write:1.3.6.1.4.1.6574.102.1.1.13.1
+#    
 # ----------------------------------------------------------------------
 # 2020-08-11  <axel.hahn@iml.unibe.ch>            initial version
 # 2020-08-13  <axel.hahn@iml.unibe.ch>            add host in label for counter data
 # 2022-10-21  v0.4  <axel.hahn@unibe.ch>          remove grep: warning: stray \ before white space
 # 2022-10-21  v0.5  <andrea.gottsponer@unibe.ch>  remove grep: warning: stray \ before white space
 # 2022-10-25  v0.6  <axel.hahn@unibe.ch>          fix empty value in performance data; shell fixes
+# 2023-05-05  v0.7  <axel.hahn@unibe.ch>          source shared func, support snmpv3; add synoio
 # ======================================================================
 
 . $(dirname $0)/inc_pluginfunctions
+. $(dirname $0)/check_snmp_includes
 
 # --- basic vars
 self_APPNAME=$( basename $0 | tr [:lower:] [:upper:] )
-self_APPVERSION=0.6
-
-SNMPCOMMUNITY="public"
-SNMPVERSION="2c"
-SNMPWALK=$(which snmpwalk)
-SNMPGET=$(which snmpget)
+self_APPVERSION=0.7
 
-HOSTNAME="127.0.0.1"
 METHOD=""
 
 # --- OID declarations
@@ -119,8 +129,14 @@ _get(){
 # is given oid a counter?
 # function resturns "true" or "false" 
 _iscounter(){
-    _getresult $1 | cut -d ":" -f1 | grep -i "Counter" >/dev/null
-    if [ $? -eq 0 ]; then
+    if _getresult $1 | cut -d ":" -f1 | grep -i "Counter" >/dev/null; then
+        echo "true"
+    else
+        echo "false"
+    fi
+}
+_isinteger(){
+    if _getresult $1 | cut -d ":" -f1 | grep -i "Integer" >/dev/null; then
         echo "true"
     else
         echo "false"
@@ -130,6 +146,15 @@ _iscounter(){
 #---------------------------------------------------
 # --- show usage
 function showHelp(){
+    _self=$( basename $0 )
+    local _methods=$(
+        _cfg_getMethods | while read -r line
+        do
+            METHOD=$(echo "$line" | cut -f 1 -d ":")
+            descr=$(_cfg_getlabel)
+            printf "                          %-10s %-50s\n" "$METHOD" "$descr"
+        done        
+    )
 cat <<EOH
 ______________________________________________________________________
 
@@ -143,31 +168,34 @@ ______________________________________________________________________
 SNMP performance data of Synology storages.
 
 USAGE:
-    ./check_snmp_data -h hostname [-C communitystring] -m method
+    $_self [options] -h SNMPTARGET
 
 PARAMETERS:
-    -h  hostname       as fqdn or ip address
-    -C  communitystr   optional: community string for snmp; default is $SNMPCOMMUNITY
-    -v                 verbose output
+    -a STRING
+        authentication params for snmpwalk/ snmpget to connect to target; 
+        default: \"-v2c -c public\" (Snmpv2 with community string \"public\")
+    -h SNMPTARGET
+        as fqdn or ip address; default: localhost
+    -f FILE
+        read authentication from config file
+        default: "/etc/icinga2/snmp.cfg"
     -m  method         what to show
                        method is one of ...
-EOH
-
-    # --- dynamic: add current methods
-    _cfg_getMethods | while read -r line
-    do
-        METHOD=$(echo "$line" | cut -f 1 -d ":")
-        descr=$(_cfg_getlabel)
-        printf "                          %-10s %-50s\n" "$METHOD" "$descr"
-    done
+$_methods
+    -v                 verbose output
 
-    # --- finish usage
-    cat <<EOH2
+CONFIG FILE:
+    The config file can be multiline and has the syntax
+    [SNMPTARGET]:[auth parameters]
+    The auth parameters set the version and all needed values to connect.
+    Snmp v2 uses a community string.
+    Snmp v3 is highly recommended (you should disable Snmp v2) and needs
+    a user and password.
 
 EXAMPLE:
-    ./check_snmp_data -h 192.168.100.12 -v -m cpu
+    $_self -h 192.168.100.12 -v -m cpu
 
-EOH2
+EOH
     ph.abort ""
 }
 
@@ -176,34 +204,42 @@ EOH2
 # MAIN
 #---------------------------------------------------
 
-while getopts h:m:v OPTNAME; do
+while getopts a:h:m:v OPTNAME; do
         case "$OPTNAME" in
 
-        h)
-                HOSTNAME="$OPTARG"
-                option_found=1
-                ;;
+        a)
+            SNMPAUTH="$OPTARG"
+            ;;
 		C)
-			    SNMPCOMMUNITY="$OPTARG"
-			    ;;
+			SNMPCOMMUNITY="$OPTARG"
+			;;
+        f)
+            SNMPCONFIG="$OPTARG"
+            ;;
+        h)
+            SNMPTARGET="$OPTARG"
+            option_found=1
+            ;;
         m)
-                METHOD="$OPTARG"
-                ;;
+            METHOD="$OPTARG"
+            ;;
         v)
-                verbose="yes"
-                _wd ""
-                ;;
+            verbose="yes"
+            _wd ""
+            ;;
         *)
-                usage
-                ;;
+            usage
+            ;;
         esac
 done
 
-if [ "$option_found" = "0" ] || [ "$HOSTNAME" = "" ] ; then
+if [ "$option_found" = "0" ] || [ "$SNMPTARGET" = "" ] ; then
     usage
     # remark: script aborts ...
 fi
 
+test -z "$SNMPAUTH" && read_config
+
 # --- read metadata of the selected METHOD
 info=$(_cfg_getlabel)
 if [ -z "$info" ]; then
@@ -218,7 +254,7 @@ looplist=( $(_cfg_dataitem 7) )
 
 # --- check for looplist
 if [ -n "$looplist" ]; then
-  nb=$($SNMPWALK -OQne -t 10 -v $SNMPVERSION -c $SNMPCOMMUNITY $HOSTNAME ${oidlist[*]} 2> /dev/null | wc -l)
+  nb=$($SNMPWALK -OQne -t $SNMPTIMEOUT $SNMPAUTH $SNMPTARGET ${oidlist[*]} 2> /dev/null | wc -l)
 
   declare -a tmpPrflist=()
   declare -a tmpOidlist=()
@@ -238,16 +274,16 @@ if [ -n "$looplist" ]; then
 fi
 
 # --- SNMPGET to all wanted oids
-SYNO=$($SNMPGET -One -t 10 -v $SNMPVERSION -c $SNMPCOMMUNITY $HOSTNAME ${oidlist[*]} 2> /dev/null)
+SYNO=$($SNMPGET -One -t $SNMPTIMEOUT $SNMPAUTH $SNMPTARGET ${oidlist[*]} 2> /dev/null)
 
 if [ $? -ne 0 ] ; then
-    $SNMPGET -One -t 10 -v $SNMPVERSION -c $SNMPCOMMUNITY $HOSTNAME ${oidlist[*]}
+    $SNMPGET -One -t $SNMPTIMEOUT $SNMPAUTH $SNMPTARGET ${oidlist[*]}
     ph.abort "Problem with SNMP request"
 fi
 
 
 # --- performance data
-typeset -i value
+# typeset -i value
 
 for index in ${!oidlist[*]}
 do
@@ -261,9 +297,13 @@ do
     else
       # handle counter data
       if [ "$(_iscounter ${oidlist[$index]})" = "true" ]; then
-          value2=$(ph.perfdeltaspeed "snmp-data-${HOSTNAME}-${method}-${label}" $value)
+          value2=$(ph.perfdeltaspeed "snmp-data-${SNMPTARGET}-${method}-${label}" $value)
           _wd "$( printf '%-14s total: %-14s delta: %6s %s per sec' $label $value $value2 $unit )"
           value=$value2
+      elif [ "$(_isinteger ${oidlist[$index]})" = "true" ]; then
+          _wd "$( printf '%-14s %s %s' $label $value $unit ) (INTEGER)"
+          value2=$( echo "${value}" | sed -E "s#([0-9]*) (.).*#\1\2#g")
+          value=${value2}
       else
           _wd "$( printf '%-14s %s %s' $label $value $unit )"
       fi
-- 
GitLab