#!/usr/bin/perl
#
use strict;
use Net::SNMP;

my $REVISION = "Revision 0.2";
my $PROGNAME = $0;
my $fanid;
my $snmpkey;
my $result;
my $oid = '1.3.6.1.4.1.231.2.10.2.2.5.2.2.1';
my $key;
my $message = 'UKNNOWN';
my $prefix  = 'UNKNOWN';
my $exit    = 3;

# cid = "column id", the oid of the column in the snmp-table
my $cid_fanStatus       = 3;
my $cid_fanPurpose      = 4;
my $cid_fanCurrentSpeed = 8;
my @col =
  ( "$oid.$cid_fanStatus", "$oid.$cid_fanPurpose",
    "$oid.$cid_fanCurrentSpeed" );

my $fanStatus = 1;
my $fanPurpose;
my $fanCurrentSpeed = 0;

## Human-readable translation of MIB-values (dummy is for shifting the index one forward)
# Status prefailure-predicted(5) means the fan will fail in near future.
# Status redundant-fan-failed(6) means a redundant fan has failed, the system
#       is not yet critical.
# Status not-manageable(7) is a fan that is available but has no management facilities.
# Status not-present(8) can be a hot-plug fan that is currently removed."

my @fanStatus = (
    "dummy", "unknown", "disabled", "ok", "fail", "prefailure-predicted",
    "redundant-fan-failed", "not-manageable", "not-present"
);
my @fanStatusDE = (
    "dummy",                      "unbekannt",
    "deaktiviert",                "ok",
    "ausgefallen",                "Ausfall zu erwarten",
    "Reserveluefter ausgefallen", "nicht verwaltbar",
    "nicht vorhanden"
);
my @fanPurpose = (
    "dummy",     "unknown", "disable",      "cpu-onchip",
    "component", "housing", "power-supply", "not-available"
);
my @fanPurposeDE = (
    "dummy",      "unbekannt", "inaktiv",  "CPU",
    "Komponente", "Gehäuse",  "Netzteil", "nicht-verfügbar"
);
my $rpm       = "rpm";
my $rpmDE     = "U/min.";
my $noSession = "No SNMP-Session possible! Probably no SNMP-Agent installed.";
my $noSessionDE =
  "Keine Verbindung zum SNMP-Agent möglich! (SNMP-Service nicht installiert?)";

# Language for the output shown to Nagios;
# can be DE (German). Anything else falls back to English.
my $lang = "DE";
if ( $lang eq "DE" ) {
    @fanPurpose = @fanPurposeDE;
    @fanStatus  = @fanStatusDE;
    $rpm        = $rpmDE;
    $noSession  = $noSessionDE;
}

my @fanspresent;
my $fid;

sub print_usage {
    print "
    Usage: $PROGNAME <host> <community>
    No tresholds are set; Checks for failed fans based
    on the fanStatus from the serverview-agent.
    \n";
}

sub print_revision() {
    print "
    $PROGNAME  - $REVISION
    Author: Ingo Lantschner
    Licence: GPL - http://www.fsf.org/licenses/gpl.txt
    \n";
}

sub print_help() {
    print_revision();
    print_usage();
    print "
    This Plugin checks the fanstatus from FuSi-Severview equiped hosts by SNMP. 
    It requires that the FuSi ServerView Agent is installed on these hosts. 
    If not, it returns an UNKNOWN state.\n
    No Warning-state is reported, this plugin returns CRITICAL if 
    one of  the fans has status failed or prefailing. 
    The output is in German as long es the variable $lang ist set to DE. 
    To change pls. open the script and set it to EN.
    \n";
}

sub main() {

    # SNMPv1 Login
    my ( $session, $error ) = Net::SNMP->session(
        -hostname  => $ARGV[0],
        -community => $ARGV[1],
        -port      => 161
    );
    if ( !defined $session ) {
        print "$noSession\n";
        exit 3;
    }
    $result = $session->get_entries( -columns => \@col );
    if ( !defined $result ) {
        $message = $session->error;
        $session->close;
        print "SNMP-Agent returned \"$message\". (Is the Fusi Serviewagent installed on the checked system?)\n";
        exit 3;
    }

    $session->close;

    #  we make a list (array) of all available fans
    foreach $snmpkey ( keys %{$result} ) {
        if ( $snmpkey =~ m/$oid.$cid_fanStatus.(\d+\.\d+)/ ) {
            push( @fanspresent, $1 );
        }
    }

 # we bring the fans into order, so that they are grouped according to their OID
    @fanspresent = Net::SNMP::oid_lex_sort(@fanspresent);
    $message     = "";
    foreach $fid (@fanspresent) {
        $fanPurpose = $$result{"$oid.$cid_fanPurpose.$fid"};
        $fanStatus  = $$result{"$oid.$cid_fanStatus.$fid"};
        if (   $fanStatus == 1
            or $fanStatus == 2
            or $fanStatus == 4
            or $fanStatus == 5
            or $fanStatus == 6 )
        {
            $prefix = "CRITICAL";
            $exit   = 2;
        }
        unless ( $prefix eq "CRITICAL" ) {
            if ( $fanStatus == 3 or $fanStatus == 8 or $fanStatus == 7 ) {
                $prefix = "OK";
                $exit   = 0;
            }
        }
        $fanCurrentSpeed = $$result{"$oid.$cid_fanCurrentSpeed.$fid"};

    # The first $fanPurpose references to the array @fanPurpose, whereas the second
    # in squarebrackets is derived from this loop.
    $message =
        "$message $fanPurpose[$fanPurpose]: $fanStatus[$fanStatus] ($fanCurrentSpeed $rpm),";
    }
    chop($message);
    print "$prefix - $message\n";
    exit $exit;

}

SWITCH: {
    if ( $ARGV[0] eq "--help" )    { print_help();     last SWITCH; }
    if ( $ARGV[0] eq "-h" )        { print_help();     last SWITCH; }
    if ( $ARGV[0] eq "--version" ) { print_revision(); last SWITCH; }
    if ( $ARGV[0] eq "-V" )        { print_revision(); last SWITCH; }
    if ( $ARGV[0] eq "-V" )        { print_revision(); last SWITCH; }
    if ( $#ARGV ne 1 ) { print_usage(); last SWITCH; }
    main();
}

