#!/usr/bin/perl -w
# -*- cperl -*-

=head1 NAME

snmp__apc - SNMP plugin to monitor APC metered and managed PDUs.

=head1 APPLICABLE SYSTEMS

This has been tested with AP7830 metered PDUs, but should work with
most other PDUs that follow the PowerNet-MIB published by APC.

=head1 CONFIGURATION

Most likely you want to use SNMP version 3 to connect to the PDUs, as
they don't support version 2 (only 1 or 3). This can be achieved by
using:

   [snmp_*_apc]
	env.version 3

Please see 'perldoc Munin::Plugin::SNMP' for further configuration
information.

=head1 MIB INFORMATION

This plugin requires the PowerNet-MIB from APC.

=head1 MAGIC MARKERS

  #%# family=snmpauto
  #%# capabilities=snmpconf

=head1 BUGS

None known.

=head1 AUTHOR

Copyright (C) 2012 Diego Elio Pettenò.

=head1 LICENSE

GPLv2

=cut

use strict;
use Munin::Plugin;
use Munin::Plugin::SNMP;

# This corresponds to PowerNet-MIB::rPDU
my $oidBase = '1.3.6.1.4.1.318.1.1.12';

# PowerNet-MIB::rPDUIdentModelNumber
my $oidModelNo   = "$oidBase.1.5";
# PowerNet-MIB::rPDUIdentSerialNumber
my $oidSerialNo  = "$oidBase.1.6";
# PowerNet-MIB::rPDULoadDevNumPhases
my $oidNumPhases = "$oidBase.2.1.2";
# PowerNet-MIB::rPDULoadPhaseConfigEntry
#  .3 -> PowerNet-MIB::rPDULoadPhaseConfigNearOverloadThreshold
#  .4 -> PowerNet-MIB::rPDULoadPhaseConfigOverloadThreshold
my $oidConfigBase = "$oidBase.2.2.1.1";
# PowerNet-MIB::rPDULoadStatusLoad (+)
my $oidPhaseLoad = "$oidBase.2.3.1.1.2";

if (defined $ARGV[0] and $ARGV[0] eq "snmpconf") {
    print "require $oidBase.2.3.1.1.2.[1-9]";
    exit 0;
}

# SNMP needed for both config and fetch.
my $session = Munin::Plugin::SNMP->session();
my $data = $session->get_entries(-columns => [$oidNumPhases,
					      $oidModelNo,
					      $oidSerialNo]);

if ($ARGV[0] and $ARGV[0] eq "config") {
    my ($host) = Munin::Plugin::SNMP->config_session();

print <<END;
host_name $host

graph_title PDU Current Drain
graph_vlabel Ampere
graph_category sensors
graph_info This graph if for $data->{"$oidModelNo.0"} serial $data->{"$oidSerialNo.0"}
graph_args --base 1000 -l 0
END

    my $phaseData = $session->get_hash(-baseoid => "$oidConfigBase",
				       -cols => { 3 => 'nearOverloadThreshold',
						  4 => 'overloadThreshold' }
				      );
    my $phaseIndex;
    for( $phaseIndex = 1; $phaseIndex <= $data->{"$oidNumPhases.0"}; $phaseIndex++ ) {
      print <<END;
phase$phaseIndex.label Phase $phaseIndex load
phase$phaseIndex.min 0
phase$phaseIndex.warning $phaseData->{$phaseIndex}->{'nearOverloadThreshold'}
phase$phaseIndex.critical $phaseData->{$phaseIndex}->{'overloadThreshold'}
END
    }

    unless ( $ENV{MUNIN_CAP_DIRTYCONFIG} == 1 ) {
      exit 0;
    }
}

my $phasesLoad = $session->get_entries(-columns => [$oidPhaseLoad]);

my $phaseIndex;
for( $phaseIndex = 1; $phaseIndex <= $data->{"$oidNumPhases.0"}; $phaseIndex++ ) {
    # the phaseLoad value is defined in dA — we might as well convert to full Amperes
    my $phaseLoad = $phasesLoad->{"$oidPhaseLoad.$phaseIndex"} / 10.0;
    print "phase$phaseIndex.value $phaseLoad\n";
}
