1#!/usr/local/bin/bash
2# -*- sh -*-
3<< END
4esxcli_env_ - Plugin to monitor ESXi host temperature or power via esxcli.
5    This plugin should be linked as esxi_env_temp or esxi_env_power.
6
7Configuration variables (/etc/munin/plugin-conf.d/):
8    Munin native:
9        host_name - Name of you ESXi host as defined in munin.conf
10        timeout - Plugin specific timeout
11    Plugin specific:
12        env.esxi_host - (REQUIRED) hostname/ip esxcli connect to
13        env.esxi_user - (REQUIRED) ESXi username to connect
14        env.esxi_password - (REQUIRED) password for user given above
15        env.cache_file - path to cache file (we do not want two or more sequential reconnections to ESXi host)
16        env.cache_max_age - if cache file is an older than this, we will fetch new data from ESXi host
17        env.warning - warning limit
18        env.critical - critical limit
19        env.margin_warning - warning limit for temperature margin values
20        env.margin_critical - critical limit for temperature margin values
21
22Please be aware that Munin has a 10 second default timeout on plugins. On some hosts esxcli can take longer
23than that, but you could set timeout in plugin config.
24
25by Oleg Selin <oleg.selin@gmail.com>
26
27#%# family=auto
28#%# capabilities=autoconf suggest
29END
30
31# Set default config if not given
32if [ -z "$cache_file" ]; then cache_file="/tmp/munin.esxcli_env.cache"; fi
33if [ -z "$cache_max_age" ]; then cache_max_age="120"; fi
34
35case $1 in
36    autoconf)
37        type -p esxcli &>/dev/null ||
38          { echo "no (missing esxcli command)" && exit 0; }
39        echo "yes"
40        exit 0;;
41    suggest)
42	echo "temp"
43        echo "power"
44        exit 0;;
45esac
46
47# Is connection information given?
48if [ -z "$esxi_host" ] || [ -z "$esxi_user" ] || [ -z $esxi_password ];
49then
50    echo "Please configure connection information"
51    exit 1
52fi
53
54### PROCESSING ###
55# Case insensitive regex
56shopt -s nocasematch
57
58# Determine sensor type
59type=${0##*/esxcli_env_}
60case "$type" in
61    temp)
62	regex="(temp.*degrees|therm.*degrees)"
63	graph_title="ESXi host temperatures"
64	graph_vlabel="C"
65	;;
66    power)
67	regex="([0-9]\\\\s?v.* volts )"
68	graph_title="ESXi host voltages"
69	graph_vlabel="V"
70	;;
71    *)
72	echo "This plugin should be linked as esxi_env_temp or esxi_env_power"
73	exit 1
74esac
75
76# Get ipmi sdr data
77if [ -f $cache_file ]; then cache=`stat --printf=%Y $cache_file`; fi
78if [ `expr $cache + $cache_max_age` -lt `date +%s` ]
79then
80	data=`esxcli -s $esxi_host -u $esxi_user -p $esxi_password hardware ipmi sdr list`
81	echo "$data" > $cache_file
82else
83	data=`cat $cache_file`
84fi
85
86# Convert to array
87OLDIFS=$IFS
88IFS=$'\n'
89sensor_names=(`echo "$data" | awk -v regexp="${regex}" 'BEGIN{IGNORECASE=1;FS="\\\\s{2,}"} $0~regexp {gsub(" ","_",$2);print tolower($2)}'`)
90sensor_labels=(`echo "$data" | awk -v regexp="${regex}" 'BEGIN{IGNORECASE=1;FS="\\\\s{2,}"} $0~regexp {print $2}'`)
91sensor_values=(`echo "$data" | awk -v regexp="${regex}" 'BEGIN{IGNORECASE=1;FS="\\\\s{2,}"} $0~regexp {print $4}'`)
92IFS=$OLDIFS
93
94# Array holds all sensor indexes
95indexes=${!sensor_names[@]}
96
97# Processing
98case $1 in
99    config) # Config run
100	echo "graph_title $graph_title"
101	echo "graph_vlabel $graph_vlabel"
102	echo "graph_category sensors"
103	for index in $indexes; do
104	   echo ${sensor_names[$index]/./,}.label ${sensor_labels[$index]}
105	   if [[ ${sensor_names[$index]} =~ margin ]]; then
106		echo ${sensor_names[$index]/./,}.warning $margin_warning
107		echo ${sensor_names[$index]/./,}.critical $margin_critical
108	   else
109	       echo ${sensor_names[$index]/./,}.warning $warning
110 	       echo ${sensor_names[$index]/./,}.critical $critical
111	   fi
112	done
113        exit 0;;
114    *) # Normal run
115	for index in $indexes; do
116	    echo ${sensor_names[$index]/./,}.value ${sensor_values[$index]}
117	done
118esac
119