root / plugins / snmp / snmp__poseidon-sensors @ e5ce7492
Historique | Voir | Annoter | Télécharger (10,5 ko)
| 1 | eec9de90 | Florian Lechner | #!/bin/bash |
|---|---|---|---|
| 2 | #==============================================================================# |
||
| 3 | # # |
||
| 4 | d7d422fa | Florian Lechner | # check status of sensor of HW Group Poseidon 3268. For more info refer to: # |
| 5 | eec9de90 | Florian Lechner | # http://www.hw-group.com/products/poseidon/poseidon_3268_en.html # |
| 6 | d7d422fa | Florian Lechner | # 2012 by Florian Lechner # |
| 7 | eec9de90 | Florian Lechner | # # |
| 8 | #==============================================================================# |
||
| 9 | # # |
||
| 10 | # This program is free software: you can redistribute it and/or modify # |
||
| 11 | # it under the terms of the GNU General Public License as published by # |
||
| 12 | # the Free Software Foundation, either version 2 of the License, or # |
||
| 13 | # (at your option) any later version. # |
||
| 14 | # # |
||
| 15 | # This program is distributed in the hope that it will be useful, # |
||
| 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # |
||
| 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # |
||
| 18 | # GNU General Public License for more details. # |
||
| 19 | # # |
||
| 20 | # You should have received a copy of the GNU General Public License # |
||
| 21 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # |
||
| 22 | # # |
||
| 23 | #==============================================================================# |
||
| 24 | |||
| 25 | # Munin autoconf and snmpautoconf magic |
||
| 26 | #%# family=auto snmpauto contrib |
||
| 27 | #%# capabilities=snmpconf |
||
| 28 | |||
| 29 | E_OK="0" # everything went allright |
||
| 30 | E_UNKNOWN="1" # "catch all" for otherwise unhandled errors |
||
| 31 | |||
| 32 | E_ARG="81" # invalid argument |
||
| 33 | E_USAGE="82" # wrong program name or arguments |
||
| 34 | E_SNMPGET="83" # error while executing the 'snmpget' utility |
||
| 35 | |||
| 36 | E_COMMANDNOTFOUND="127" # unable to locate binary |
||
| 37 | |||
| 38 | #==============================================================================# |
||
| 39 | # SNMP OIDs from the Poseidon MIB # |
||
| 40 | #==============================================================================# |
||
| 41 | |||
| 42 | SYS_LOC_OID=".1.3.6.1.2.1.1.6.0" # SNMP-location |
||
| 43 | SYS_NAME_OID=".1.3.6.1.2.1.1.5.0" # device name (string) |
||
| 44 | SYS_DESCR_OID=".1.3.6.1.2.1.1.1" # text describing the device |
||
| 45 | SYS_UPTIME_OID=".1.3.6.1.2.1.1.3.0" # time(in tens of milliseconds |
||
| 46 | #+ since the last reboot |
||
| 47 | IN_NAME_OID=".1.3.6.1.4.1.21796.3.3.1.1.3." # binary input name (string) |
||
| 48 | IN_STATE_OID=".1.3.6.1.4.1.21796.3.3.1.1.2." # binary input states(integer) |
||
| 49 | IN_ALARM_OID=".1.3.6.1.4.1.21796.3.3.1.1.4." # alarm for the binary input, |
||
| 50 | #+ generated by the device |
||
| 51 | #+ under defined conditions |
||
| 52 | #+ 0=Invalid, 1=Normal, |
||
| 53 | #+ 2=AlarmState, 3=Alarm |
||
| 54 | SENS_NAME_OID=".1.3.6.1.4.1.21796.3.3.3.1.2." # sensor name (string) |
||
| 55 | SENS_STATE_OID=".1.3.6.1.4.1.21796.3.3.3.1.4." # binary input states(integer) |
||
| 56 | SENS_VALUE_OID=".1.3.6.1.4.1.21796.3.3.3.1.6." # integer (decimal * 10) |
||
| 57 | SENS_ID_OID=".1.3.6.1.4.1.21796.3.3.99.1.2.1.4." # unique sensor ID (integer) |
||
| 58 | #+ representation of the |
||
| 59 | #+ temperature (integer) |
||
| 60 | SENS_UNIT_OID=".1.3.6.1.4.1.21796.3.3.3.1.9." # 0=°C,1=°F,2=°K,3=%,4=V,5=mA, |
||
| 61 | RTS_OUTPUT_OID=".1.3.6.1.4.1.21796.3.3.2.1.2." # binary input state (integer) |
||
| 62 | #+ 6=unknown, 7=pulse, 8=switch |
||
| 63 | |||
| 64 | # define some Poseidon specific stuff: |
||
| 65 | STATE_OK="1" |
||
| 66 | STATE_WARN="2" |
||
| 67 | STATE_CRIT="3" |
||
| 68 | UNITS=("C" "F" "K" "%" "V" "mA" "unknown" "pulse" "switch")
|
||
| 69 | TYPES=("Temp" "Temp" "Temp" "Hum" "Volt" "Curr" "Unkn" "Pulse" "Switch")
|
||
| 70 | |||
| 71 | declare -A sensorsOfType |
||
| 72 | IFS=" |
||
| 73 | " |
||
| 74 | |||
| 75 | #==============================================================================# |
||
| 76 | |||
| 77 | # printMuninConfig () |
||
| 78 | # print output for munin auto configuration |
||
| 79 | printMuninConfig () {
|
||
| 80 | if [ ! $hostAddr = 'localhost' ]; then |
||
| 81 | cat <<- EOT |
||
| 82 | host_name $hostAddr |
||
| 83 | EOT |
||
| 84 | fi |
||
| 85 | |||
| 86 | for ((_sensorType=0; _sensorType<=${#UNITS[*]};_sensorType++)); do
|
||
| 87 | # skip graphs without sensors |
||
| 88 | if [ -z "${sensorsOfType[$_sensorType]}" ]; then
|
||
| 89 | continue |
||
| 90 | fi |
||
| 91 | |||
| 92 | _firstSensor="1" |
||
| 93 | # print specific config for each sensor |
||
| 94 | for _sensorNr in ${sensorsOfType[$_sensorType]}; do
|
||
| 95 | getSensorData $_sensorNr |
||
| 96 | getSystemInfo |
||
| 97 | |||
| 98 | if [ $_firstSensor = "1" ]; then |
||
| 99 | # graph headers |
||
| 100 | cat <<- EOT |
||
| 101 | multigraph $sensorType |
||
| 102 | graph_title $sensorLocation - $sensorType [$sensorUnit] |
||
| 103 | graph_args --base 1000 -l 0 |
||
| 104 | graph_vlabel $sensorUnit |
||
| 105 | graph_category environment |
||
| 106 | graph_info This graph shows $sensorType history. |
||
| 107 | EOT |
||
| 108 | fi |
||
| 109 | _firstSensor="0" |
||
| 110 | cat <<- EOT |
||
| 111 | $sensorType$_sensorNr.label $sensorName |
||
| 112 | $sensorType$_sensorNr.info This graph shows $sensorType$_sensorNr history. |
||
| 113 | $sensorType$_sensorNr.draw LINE2 |
||
| 114 | EOT |
||
| 115 | done |
||
| 116 | done |
||
| 117 | } |
||
| 118 | |||
| 119 | # printMuninSnmpConfig () |
||
| 120 | # print output for munin snmp auto configuration |
||
| 121 | printMuninSnmpConfig () {
|
||
| 122 | cat <<- EOT |
||
| 123 | require $SENS_VALUE_OID$sensorNumber [0-9] |
||
| 124 | require $SENS_STATE_OID$sensorNumber |
||
| 125 | EOT |
||
| 126 | return 0; |
||
| 127 | } |
||
| 128 | |||
| 129 | # printMuninStatus () |
||
| 130 | # print status output for munin |
||
| 131 | printMuninStatus () {
|
||
| 132 | for ((_sensorType=0; _sensorType<=${#UNITS[*]};_sensorType++)); do
|
||
| 133 | # skip graphs without sensors |
||
| 134 | if [ -z "${sensorsOfType[$_sensorType]}" ]; then
|
||
| 135 | continue |
||
| 136 | fi |
||
| 137 | _firstSensor="1" |
||
| 138 | |||
| 139 | # print config section |
||
| 140 | for _sensorNr in ${sensorsOfType[$_sensorType]}; do
|
||
| 141 | getSensorData $_sensorNr |
||
| 142 | if [ $_firstSensor = "1" ]; then |
||
| 143 | # graph headers |
||
| 144 | cat <<- EOT |
||
| 145 | multigraph $sensorType |
||
| 146 | EOT |
||
| 147 | fi |
||
| 148 | _firstSensor="0" |
||
| 149 | |||
| 150 | # print graph details |
||
| 151 | cat <<- EOT |
||
| 152 | $sensorType$_sensorNr.value $(( $sensorValue / 10 )) |
||
| 153 | EOT |
||
| 154 | done |
||
| 155 | echo "" |
||
| 156 | done |
||
| 157 | } |
||
| 158 | |||
| 159 | # getSensorData(sensorNr) |
||
| 160 | # fetch state, value, name unit and sensor type for the sensor |
||
| 161 | #+ with the number "sensorNr" |
||
| 162 | getSensorData() {
|
||
| 163 | _sensorNr=$1 |
||
| 164 | sensorState=`snmpGet $hostAddr $SENS_STATE_OID$_sensorNr || err \ |
||
| 165 | "Fatal: snmpget failed with code \"$?\"! Exiting..." $E_SNMPGET` |
||
| 166 | sensorValue=`snmpGet $hostAddr $SENS_VALUE_OID$_sensorNr || err \ |
||
| 167 | "Fatal: snmpget failed with code \"$?\"! Exiting..." $E_SNMPGET` |
||
| 168 | sensorName=`snmpGet $hostAddr $SENS_NAME_OID$_sensorNr || err \ |
||
| 169 | "Fatal: snmpget failed with code \"$?\"! Exiting..." $E_SNMPGET` |
||
| 170 | sensorUnit=`getSensorUnitString $_sensorNr` |
||
| 171 | sensorType=`getSensorType $_sensorNr` |
||
| 172 | } |
||
| 173 | |||
| 174 | # getSystemInfo() |
||
| 175 | # fetch general information about the system |
||
| 176 | getSystemInfo() {
|
||
| 177 | sensorLocation="`snmpGet $hostAddr $SYS_LOC_OID`" |
||
| 178 | } |
||
| 179 | |||
| 180 | # snmpGet (hostAddr, OID) |
||
| 181 | # use snmpget to fetch a given OID, using above configuration |
||
| 182 | snmpGet () {
|
||
| 183 | _oid="$2" |
||
| 184 | |||
| 185 | _host="$1" |
||
| 186 | _exit="0" |
||
| 187 | |||
| 188 | # fetch the requested OID |
||
| 189 | _longValue="`snmpget -O v\ |
||
| 190 | -m $MIBS\ |
||
| 191 | -v $SNMPVERSION\ |
||
| 192 | d7d422fa | Florian Lechner | -c $SNMPCOMMUNITY\ |
| 193 | eec9de90 | Florian Lechner | $_host $_oid 2>/dev/null`" |
| 194 | |||
| 195 | _exitStatus="$?" |
||
| 196 | |||
| 197 | echo ${_longValue#*:} # remove the type from the answer
|
||
| 198 | return $_exitStatus |
||
| 199 | } |
||
| 200 | |||
| 201 | # get unit (string) |
||
| 202 | #+ find out the unit of the output of a given sensor. possible units are: |
||
| 203 | #+ "C" "F" "K" "%" "V" "mA" "unknown" "pulse" "switch" |
||
| 204 | getSensorUnitString () {
|
||
| 205 | _sensorNr=$1 |
||
| 206 | _sensorUnit=`snmpGet $hostAddr $SENS_UNIT_OID$_sensorNr || err \ |
||
| 207 | "Fatal: snmpget failed with code \"$?\"! Exiting..." $E_SNMPGET` |
||
| 208 | echo ${UNITS[$_sensorUnit]}
|
||
| 209 | } |
||
| 210 | |||
| 211 | # get type (string) |
||
| 212 | #+ find out what type of sensor we are dealing with. possible types are: |
||
| 213 | #+ "Temp" "Hum" "Volt" "Curr" "Unkn" "Pulse" "Switch" |
||
| 214 | getSensorType () {
|
||
| 215 | _sensorNr=$1 |
||
| 216 | _sensorUnit=`snmpGet $hostAddr $SENS_UNIT_OID$_sensorNr || err \ |
||
| 217 | "Fatal: snmpget failed with code \"$?\"! Exiting..." $E_SNMPGET` |
||
| 218 | echo ${TYPES[$_sensorUnit]}
|
||
| 219 | } |
||
| 220 | |||
| 221 | # getAvailableSensorsByType () |
||
| 222 | # check what sensors are available and store them |
||
| 223 | #+ in the array for the respective unit |
||
| 224 | getAvailableSensorsByType () {
|
||
| 225 | _thisSensorNr="1" |
||
| 226 | |||
| 227 | # initial fetch |
||
| 228 | _snmpget=`snmpGet $hostAddr $SENS_UNIT_OID$_thisSensorNr` |
||
| 229 | _nextSensorExits=$? |
||
| 230 | _unit=`echo "$_snmpget" | tr -d " "` |
||
| 231 | |||
| 232 | # add next sensor if it exists |
||
| 233 | while [ true ]; do |
||
| 234 | # add sensors of the same type to a list |
||
| 235 | sensorsOfType[$_unit]="${sensorsOfType[$_unit]} $_thisSensorNr"
|
||
| 236 | |||
| 237 | # fetch next sensor |
||
| 238 | _thisSensorNr=$(($_thisSensorNr+1)) |
||
| 239 | _snmpget=`snmpGet $hostAddr $SENS_UNIT_OID$_thisSensorNr` |
||
| 240 | _nextSensorExits=$? |
||
| 241 | |||
| 242 | # are we done? |
||
| 243 | if [ $_nextSensorExits -ne 0 ]; then |
||
| 244 | break |
||
| 245 | fi |
||
| 246 | |||
| 247 | _unit=`echo "$_snmpget" |cut -d" " -f 4` |
||
| 248 | done |
||
| 249 | } |
||
| 250 | |||
| 251 | # sanitize (<string>) |
||
| 252 | # use bash builtin substitutions to sanitize string |
||
| 253 | #+ allowed chars are: a-z,A-Z,0-9 and "." |
||
| 254 | #+ if chars have been removed return 1, else return 0 |
||
| 255 | sanitize () {
|
||
| 256 | input="$1" |
||
| 257 | sanitizedInput="${1//[^a-zA-Z0-9.]/}"
|
||
| 258 | echo "$sanitizedInput" |
||
| 259 | if [ "$input" = "$sanitizedInput" ]; then |
||
| 260 | return 0 |
||
| 261 | else |
||
| 262 | return 1 |
||
| 263 | fi |
||
| 264 | } |
||
| 265 | |||
| 266 | d7d422fa | Florian Lechner | # usage () |
| 267 | # print usage |
||
| 268 | eec9de90 | Florian Lechner | usage () {
|
| 269 | d7d422fa | Florian Lechner | echo "usage: snmp_<host>_poseidon-sensors [config|snmpconf]" 1>&2 |
| 270 | exit $E_USAGE |
||
| 271 | eec9de90 | Florian Lechner | } |
| 272 | |||
| 273 | # err (ErrorMsg, Exitcode) |
||
| 274 | # basic error handling |
||
| 275 | err () {
|
||
| 276 | if [ $# -eq 2 -a "$2" -lt 256 ]; then |
||
| 277 | _errorMsg="$1" |
||
| 278 | _exitCode="$2" |
||
| 279 | else |
||
| 280 | _errorMsg="Fatal: An unknown error occured! Exiting..." |
||
| 281 | _exitCode="$E_UNKNOWN" |
||
| 282 | |||
| 283 | fi |
||
| 284 | |||
| 285 | # print error message to STDERR ... |
||
| 286 | echo "$_errorMsg" >&2 |
||
| 287 | # ... and exit with error code. |
||
| 288 | exit $_exitCode |
||
| 289 | } |
||
| 290 | |||
| 291 | #==============================================================================# |
||
| 292 | |||
| 293 | d7d422fa | Florian Lechner | # SNMP Config |
| 294 | MIBS=":" # we don't use any configured MIBs so we don't |
||
| 295 | #+ have to deal with errors in the MIBs |
||
| 296 | if [ -z $SNMPVERSION ]; then |
||
| 297 | SNMPVERSION="1" # as of firmware 3.1.5 only SNMPv1 is supported |
||
| 298 | fi |
||
| 299 | |||
| 300 | if [ -z $SNMPCOMMUNITY ]; then |
||
| 301 | SNMPCOMMUNITY="public" # SNMP community string to read from the device |
||
| 302 | fi |
||
| 303 | |||
| 304 | eec9de90 | Florian Lechner | # handle -h option |
| 305 | while getopts ":h" opt; do |
||
| 306 | case $opt in |
||
| 307 | h) usage |
||
| 308 | ;; |
||
| 309 | \?) echo "Invalid option: -$OPTARG" >&2 |
||
| 310 | usage |
||
| 311 | ;; |
||
| 312 | esac |
||
| 313 | done |
||
| 314 | |||
| 315 | # check for snmpget binary |
||
| 316 | if [ ! -x `which snmpget` ]; then |
||
| 317 | err "Fatal: unable to locate \'snmpget\'! Exiting..." $E_COMMANDNOTFOUND |
||
| 318 | fi |
||
| 319 | |||
| 320 | d7d422fa | Florian Lechner | # extract pluginname ... |
| 321 | myName="`basename "$0" | cut -d "_" -f 1,3`" |
||
| 322 | |||
| 323 | # ...and hostname |
||
| 324 | hostAddr="`basename "$0" | cut -d "_" -f 2`" |
||
| 325 | eec9de90 | Florian Lechner | |
| 326 | d7d422fa | Florian Lechner | if [ "$myName" = "snmp_poseidon-sensors" ]; then |
| 327 | eec9de90 | Florian Lechner | hostAddr=`sanitize $hostAddr || err \ |
| 328 | "Fatal: Invalid argument \"$hostAddr\"! Exiting..." $E_ARG` |
||
| 329 | if [ -z "$hostAddr" ]; then |
||
| 330 | usage munin |
||
| 331 | fi |
||
| 332 | getAvailableSensorsByType |
||
| 333 | if [ "$1" = "config" ]; then |
||
| 334 | printMuninConfig |
||
| 335 | exit $E_OK |
||
| 336 | elif [ "$1" = "snmpconfig" ]; then |
||
| 337 | printMuninSnmpConfig |
||
| 338 | exit $E_OK |
||
| 339 | else |
||
| 340 | printMuninStatus |
||
| 341 | exit $E_OK |
||
| 342 | fi |
||
| 343 | else |
||
| 344 | usage |
||
| 345 | fi |
