Skip to content
Snippets Groups Projects
Select Git revision
  • 40a1685c14870a7e18a96146e1c78bbc4b1e1353
  • master default protected
  • simple-task/7248-eol-check-add-node-22
  • 6877_check_iml_deployment
4 results

check_snmp_printer

Blame
  • check_snmp_synology 13.36 KiB
    #!/bin/bash
    # check_snmp_synology for nagios version 1.2
    # 30.04.2013        Nicolas Ordonez, Switzerland
    # 08.08.2020        Axel Hahn: add update, community string
    # 03.05.2023  v1.2  Axel Hahn: support Snmpv3 connections
    # 09.05.2023  v1.3  Axel Hahn: allow complete check or single check(s)
    # 12.05.2023  v1.4  Axel Hahn: no raid size check (DSM 5.x)
    # ----------------------------------------------------------------------
    # this plugin check the health of your Synology NAS
    # - System status (Power, Fans)
    # - Disks status 
    # - RAID status
    # - available updates
    #
    # Tested with DSM 5.2 ... 6.2 ... 6.4 ... 7.1
    # ----------------------------------------------------------------------
    # see docs:
    # https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_DiskStation_MIB_Guide.pdf
    # ----------------------------------------------------------------------
    
    . $(dirname $0)/inc_pluginfunctions
    . $(dirname $0)/check_snmp_includes
    
    # --- basic vars
    
    self_APPNAME=$( basename $0 | tr [:lower:] [:upper:] )
    self_APPVERSION=1.4
    
    SNMPOUTPUT=
    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
    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)
    
    FLAG_SINGLECHECK=0
    
    # available single checks
    FLAG_SYSTEM=1
    FLAG_DISK=1
    FLAG_UPDATE=1
    FLAG_TEMPERATURE=1
    
    _self=$( basename $0 )
    USAGE="
    ______________________________________________________________________
    
    $self_APPNAME 
    v$self_APPVERSION
    
    Based on script of Nicolas Ordonez.
    
    Institute for Medical Education - University of Bern
    Licence: GNU GPL 3
    ______________________________________________________________________
    
    Check health of a Synology drive using SNMP.
    
    SYNTAX:
        $_self [options] -h TARGET
    
    OPTIONS:
        -a STRING
            Authentication params for snmpwalk/ snmpget to connect to target; 
            default: \"-v2c -c public\" (Snmpv2 with community string \"public\")
        -h SNMPTARGET
            Set a target to connect as fqdn or ip address; default: localhost
        -f FILE
            Read authentication from config file. See section 'CONFIG FILE' below.
            default: \"/etc/icinga2/snmp.cfg\"
    
        By default all checks will be executed. You can linit the executed checks
        by naming single checks:
    
        -s  System check:
            - Show system data: model, serial number, DSM version
            - System status
            - Power status
            - System fan Status
            - CPU fan status
        -d  Disk check: 
            - status and temperature of each hard disk
            - status of all raid volumes
            - free disk space
        -u  Update check; check switches to warning if an update is available
        -t  Temerature check
    
        -v  Enable detailed output of the checks. It is recommended for
            system status and disk status.
    
    CONFIG FILE:
        The config file can be multiline and has the syntax
        [SNMPTARGET[,target2]]:[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:
        server-01.example.com:-v 3 -l authnoPriv -a SHA -u snmpmonitor -A password-for-server-01
        server-02.example.com,192.168.0.4:-v 3 -l authnoPriv -a SHA -u snmpmonitor -A password-for-server-02
    
    EXAMPLE:
    
        $_self -h server-01.example.com -v
            Show complete Synology status of server-01 using connect data from 
            /etc/icinga2/snmp.cfg
    
        $_self -h server-01.example.com -v -f /opt/somewhere/snmp.conf
            Show complete Synology status of server-01 using connect data from 
            custom config file
    
        $_self -h server-01.example.com -u
            Make a single check if update is available.
    "
    
    # ----------------------------------------------------------------------
    # FUNCTIONS
    # ----------------------------------------------------------------------
    
    # write verbose text with details in 2 columns
    # param  string  label
    # param  string  value
    _wd()
    {
        if [ "$verbose" = "yes" ] ; then 
            _label=$1
            shift 1
            out+=$( printf "%-25s %s" "${_label}" "$*" )"
    "
        fi
    }
    
    # get a value from SNMP output data
    # param  string  mib string
    _get(){
        echo "$SNMPOUTPUT" | grep "${1} " | cut -d "=" -f2 | cut -f 2- -d " "
    }
    
    # show usage and abort
    usage()
    {
            ph.abort "$USAGE"
    }
    
    # disable all flags to perform single checks
    # see param check in main section
    _disableflags(){
        if [ $FLAG_SINGLECHECK -ne 1 ]; then
            FLAG_SINGLECHECK=1
            FLAG_SYSTEM=0
            FLAG_DISK=0
            FLAG_UPDATE=0
            FLAG_TEMPERATURE=0
        fi
    }
    
    # add something to the status line (1st line) in monitoring output
    _add_status(){
        test -n "$healthString" && healthString+=", "
        healthString+="$*"
    }
    
    
    # ----------------------------------------------------------------------
    # MAIN
    # ----------------------------------------------------------------------
    
    test $# -eq 0 && usage
    
    while getopts a:h:f:vsdut OPTNAME; do
        case "$OPTNAME" in
            a)
                SNMPAUTH="$OPTARG"
                ;;
            f)
                SNMPCONFIG="$OPTARG"
                ;;
            h)
                SNMPTARGET="$OPTARG"
                ;;
            v)
                verbose="yes"
                ;;
    
            # Flags:
            s)
                _disableflags
                FLAG_SYSTEM=1
                ;;
            t)
                _disableflags
                FLAG_TEMPERATURE=1
                ;;
            u)
                _disableflags
                FLAG_UPDATE=1
                ;;
            d)
                _disableflags
                FLAG_DISK=1
                ;;
            *)
                usage
                ;;
        esac
    done
    
    
    # --- read config to get the authentication params for snmp commands
    
    test -z "$SNMPAUTH" && read_config
    
    # --- read raid and disks to get its single OIDs
    if [ $FLAG_DISK -ne 0 ]; then
        nbDisk="$( $SNMPWALK -OQne -t $SNMPTIMEOUT ${SNMPAUTH} $SNMPTARGET $OID_diskID   2> /dev/null | wc -l )"
        nbRAID="$( $SNMPWALK -OQne -t $SNMPTIMEOUT ${SNMPAUTH} $SNMPTARGET $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
    fi
    
    # --- SNPGET to all wanted oids
    
    OIDLIST=""
    test $FLAG_SYSTEM      -ne 0 && OIDLIST+="$OID_model $OID_serialNumber $OID_DSMUpdateAvailable $OID_DSMVersion $OID_systemStatus $OID_powerStatus $OID_systemFanStatus $OID_CPUFanStatus "
    test $FLAG_DISK        -ne 0 && OIDLIST+="$OID_disk $OID_RAID "
    test $FLAG_UPDATE      -ne 0 && test $FLAG_SYSTEM -eq 0 && OIDLIST+="$OID_DSMUpdateAvailable $OID_DSMVersion "
    test $FLAG_TEMPERATURE -ne 0 && OIDLIST+="$OID_temp "
    
    
    if ! SNMPOUTPUT=$( $SNMPGET -OQne -t $SNMPTIMEOUT ${SNMPAUTH} $SNMPTARGET $OIDLIST 2>&1 ); then
        ph.abort "SNMP request failed. $SNMPOUTPUT"
    fi
    SNMPOUTPUT=$( echo "$SNMPOUTPUT" | sed 's/^[ \t]*//;s/[ \t]*$//' )
    
    _wd ""
    
    # ----------------------------------------------------------------------
    # GENERATE OUTPUT
    # ----------------------------------------------------------------------
    
    # ---------- check system data
    if [ $FLAG_SYSTEM -ne 0 ]; then
        _wd "---------- INFORMATION"
        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"
    
        _add_status "  Synology $model (s/n: $serialNumber, $DSMVersion)"
    fi
    
    # ---------- check update
    if [ $FLAG_SYSTEM -ne 0 -o $FLAG_UPDATE -ne 0 ]; then
        typeset -i DSMupdate=$(_get $OID_DSMUpdateAvailable)
    
        # test $FLAG_SINGLECHECK -ne 0 || ( _wd "Update available:  ${aStatusUpgrade[$DSMupdate]} ($DSMupdate)"; _wd "" )
        _wd "Update available:" "${aStatusUpgrade[$DSMupdate]} ($DSMupdate)"
        _wd ""
        if [ $DSMupdate -eq 1 ] ; then
            ph.setStatus "warning"
            _add_status "Update available"
        else
            test $FLAG_SINGLECHECK -ne 0 && _add_status "Up to date"
        fi
    fi
    
    if [ $FLAG_SYSTEM -ne 0 ]; then
        _wd "---------- SYSTEM"
    
        # --- Check system status
        systemStatus="$(_get $OID_systemStatus)"
    
        if [ "$systemStatus" != "1" ] ; then
            if [ "$systemStatus" = "2" ] ; then      systemStatus="Failed";          fi
            ph.setStatus "critical"
            _add_status "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"
            _add_status "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"
            _add_status "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"
            _add_status "CPU fan status: $CPUFanStatus "
        else
            CPUFanStatus="Normal"
        fi
        _wd "CPU Fan Status:" "$CPUFanStatus"
    fi
    
    # ---------- check temperature
    if [ $FLAG_TEMPERATURE -ne 0 ]; then
        # --- Show temperature
        DeviceTemperature=$(_get $OID_temp)
        _wd "NAS temperature:" "$DeviceTemperature °C"
    
        if [ $FLAG_SINGLECHECK -ne 0 ]; then
            _add_status "NAS temperature: $DeviceTemperature °C"
            ph.perfadd "temp" "$DeviceTemperature"
        fi
        test $FLAG_DISK -ne 0 && _wd ""
    fi
    
    # ---------- Check all disk status + volume + raid
    if [ $FLAG_DISK -ne 0 ]; then
        RAIDName=$(_get $OID_RAIDName)
        RAIDStatus=$(_get $OID_RAIDStatus)
        DISKOK=1
    
        _wd "---------- STORAGE"
        _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"
                DISKOK=0
                test $FLAG_SINGLECHECK -ne 0 && _add_status "NAS temperature: $DeviceTemperature °C"
                _add_status "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 volumes:" "$nbRAID"
        for i in $(seq 1 $nbRAID);
        do
            RAIDName[$i]=$(_get $OID_RAIDName.$(($i-1)))
            iRAIDStatus=$(_get $OID_RAIDStatus.$(($i-1)))
    
            RAIDStatus[$i]=${aStatusRaid[${iRAIDStatus}]}
    
            if [ "$iRAIDStatus" != "1" ] ; then
                DISKOK=0
                ph.setStatus "critical"
                _add_status "RAID status: ($RAIDName ): $RAIDStatus[$i] "
            fi
    
            # size in integer GB
            if _get $OID_RAIDSize.$(($i-1)) | grep "[0-9]" >/dev/null; 
            then
                    iRAIDSize=$(( $(_get $OID_RAIDSize.$(($i-1))) / 1024/1024/1024 ))
                    iRAIDFree=$(( $(_get $OID_RAIDFree.$(($i-1))) / 1024/1024/1024 ))
                    iFree=$(( iRAIDFree*100/$iRAIDSize ))
    
                    _wd "  ${RAIDName[$i]} status: ${RAIDStatus[$i]} ($iRAIDStatus) - size $iRAIDSize GB, free $iRAIDFree GB (${iFree}%)"
            else
                    _wd "  ${RAIDName[$i]} status: ${RAIDStatus[$i]} ($iRAIDStatus) - (size not available)"
            fi
        done
    
        if [ $DISKOK -eq 1 ]; then
            test $FLAG_SINGLECHECK -ne 0 && _add_status "Disks and volumes are fine."
        fi
    fi
    
    # --- output status
    ph.status "$healthString"
    echo "$out"
    
    ph.exit