#!/bin/sh
# -*- sh -*-

: << =cut

=head1 NAME

freeipmi_ - Plugin to monitor temperature or fan speed using FreeIPMI

=head1 CONFIGURATION

=head2 ENVIRONMENT VARIABLES

When used to monitor a foreign host, this plugins use the variables
IPMI_USERNAME and IPMI_PASSWORD to log in on the remote system.

=head2 WILDCARD PLUGIN

You can monitor either the current system (via /dev/ipmi0 and the
like) or a remote system (via the LAN protocols), and for each of the
two options you can select your sensors:

 - fans;
 - temp;
 - power;
 - current;
 - voltage.

When used for the local host, the plugin should be linked as, e.g.,
'ipmi_temp', whereas when used to monitor a foreign host it should be,
e.g., 'ipmi_192.168.0.253_temp'.

=head1 NOTE

=head1 AUTHOR

Rewritten by Diego Elio Pettenò <flameeyes@flameeyes.eu>.
Based on the work of Nicolai Langfeldt <janl@linpro.no>, Logilab and
Peter Palfrader.

=head1 LICENSE

GPLv2

=head1 MAGIC MARKERS

 #%# family=auto
 #%# capabilities=autoconf suggest

=cut

#### Parse commandline to determine what the job is

_ipmisensors() {
    params="--quiet-cache --comma-separated-output --no-header-output --ignore-not-available-sensors"
    if [ "x${hostname}" != "x" ]; then
	params="${params} --hostname=${hostname}"
	[ "x${IPMI_USERNAME}" != "x" ] && params="${params} --username=${IPMI_USERNAME}"
	[ "x${IPMI_PASSWORD}" != "x" ] && params="${params} --password=${IPMI_PASSWORD}"
    fi

    if ! ipmi-sensors ${params} --output-sensor-thresholds "$@"; then
	ipmi-sensors ${params} "$@"
    fi
}

# extract and eventual hostname out of the called name; we
# have to check whether it's set to "u" as that's what happens
# when the compatibility with ipmi_sensor_ is used.
hostname1=${0#*_}
hostname=${hostname1%%_*}
if [ "x${hostname}" = "xu" -o "x${hostname}" = "x${hostname1}" ]; then
    hostname=""
fi

case $0 in
    *_temp|*_u_degrees_c)
	title="Temperatures"
	vlabel="degrees Celsius"
	type=Temperature
	unit=C
	;;
    *_fans|*_u_rpm)
	title="Fan speeds"
	vlabel="Rotations per Minute (RPM)"
	type=Fan
	unit=RPM
	;;
    *_power|*_u_watts)
	title="Power consumption"
	vlabel="Watts"
	type=Current
	unit=W
	;;
    *_current|*_u_amps)
	title="Current drain"
	vlabel="Amperes"
	type=Current
	unit=A
	;;
    *_voltage|*_u_volts)
	title="Voltages"
	vlabel="Volts"
	type=Voltage
	unit=V
	;;
    *)
	if [ x"$1" != x"autoconf" -a x"$1" != x"suggest" ]; then
	    echo "Please invoke as one of the supported sensors types:" >&2
	    echo freeipmi_{temp,fans,power,current} >&2
	    exit 1
	fi
esac

case $1 in
    autoconf)
	if ! command -v ipmi-sensors >/dev/null 2>&1 ; then
	    echo 'no (missing ipmi-sensors command)'
	    exit 0
	fi

	if ! _ipmisensors -t OS_Boot >/dev/null 2>&1 ; then
	    echo 'no (unable to access IPMI device)'
	    exit 0
	fi

	echo yes
	exit 0
	;;
    suggest)
	_ipmisensors | awk -F, '
$3 == "Temperature" { print "temp"; }
$3 == "Fan" { print "fans"; }
$3 == "Current" && $5 == "W" { print "power"; }
$3 == "Current" && $5 == "A" { print "current"; }
$3 == "Voltage" { print "voltage"; }
'
	exit 0;;
    config)
	cat - <<EOF
graph_title ${title} based on IPMI sensors
graph_vlabel ${vlabel}
graph_category Sensors
EOF

	if [ "x${hostname}" != "x" ]; then
	    echo "host_name ${hostname}"
	fi
	;;
esac

_ipmisensors -t ${type} | awk -F, -v CONFIG=$1 -v UNIT=$unit '
$5 == UNIT {
    if ( CONFIG != "config" ) {
      printf("ipmi%s.value %s\n", $1, $4);
    } else {
      printf("ipmi%s.label %s\n", $1, $2);

      # This can only happen if FreeIPMI is new enough
      if ( NF == 12 ) {
        if ( $8 != "N/A" && $10 != "N/A" )
          printf("ipmi%s.warning %s:%s\n", $1, $8, $10);
        else if ( $8 == "N/A" && $10 != "N/A" )
          printf("ipmi%s.warning :%s\n", $1, $10);
        else if ( $8 != "N/A" && $10 == "N/A" )
          printf("ipmi%s.warning %s:\n", $1, $8);

        if ( $7 != "N/A" && $11 != "N/A" )
          printf("ipmi%s.critical %s:%s\n", $1, $7, $11);
        else if ( $7 == "N/A" && $11 != "N/A" )
          printf("ipmi%s.critical :%s\n", $1, $11);
        else if ( $7 != "N/A" && $11 == "N/A" )
          printf("ipmi%s.critical %s:\n", $1, $7);
      }
  }
}
'

# vim: syntax=sh ts=4 et
