File check_infortrend of Package monitoring-plugins-infortrend
#!/usr/bin/perl
# \file check_infortrend
# \author Bill Hill
# \date November 2008
# \version $Id: check_infortrend,v 1.1 2008/12/01 08:58:25 bill Exp $
# \par
# Address:
# MRC Human Genetics Unit,
# Western General Hospital,
# Edinburgh, EH4 2XU, UK.
# \par
# Copyright (C) 2008 Medical research Council, UK.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be
# useful but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
# \brief Nagios plugin to check the status of an Infortrend storage
# array. This script has been hacked to work with the telnet
# interface of the Infortrend arrays.
# \todo -
# \bug None known.
use strict;
use warnings;
use File::Spec::Unix;
use Getopt::Long;
use Net::Telnet;
my %statusTab =
(
'OK' => 0,
'WARNING' => 1,
'CRITICAL' => 2,
'UNKNOWN' => 3
);
my %statusStrTab =
(
0 => "OK",
1 => "WARNING",
2 => "CRITICAL",
3 => "UNKNOWN"
);
my $arrayname = 'array';
my $arraypwd = '';
my $debug = 0;
my $drvCnt = 0;
my $drvOkCnt = 0;
my @drvStatus;
my $expDrvCnt = 16;
my $maxDrvCnt = 16;
my $esc = "\x1b";
my $help = 0;
my $mesg = '';
my $model = "T6100F"; # Known models are T6100F, PV610F and A24F-R2430
my $progname = 'check_infortrend';
my $state = $statusTab{'UNKNOWN'};
sub makeExit
{
my $msg = $_[0];
print "$statusStrTab{$state} - array $arrayname";
if(length($msg) > 0)
{
print " ($msg)";
}
print ".\n";
exit($state);
}
sub showUsage
{
print STDERR "Nagios plugin which checks the status of an infortrend\n";
print STDERR "EonStor RAID array.\n";
print STDERR "Usage: $progname [options]\n";
print STDERR "where the valid options are\n";
print STDERR " -h, --help Output this usage information.\n";
print STDERR " -d, --debug Debug level.\n";
print STDERR " -a, --array The name of the infortrend array.\n";
print STDERR " -p, --password The password for the array.\n";
print STDERR " -m, --model The model of array (known models are:\n";
print STDERR " T6100F, PV610F and A24F-R2430.\n";
print STDERR " -e, --expected The number of drives expected.\n";
}
sub initialScreenSleep()
{
my $ary = $_[0];
my $cnt = 5;
for(my $idx = 0; $idx < $cnt; ++$idx)
{
$ary->put($esc);
sleep(1);
}
}
sub initialScreenGoble()
{
my $ary = $_[0];
my $cnt = 4;
my $irs;
if($debug > 0)
{
print "selecting initial screen\n";
}
$irs = $ary->input_record_separator("Enter:Main Menu");
for(my $idx = 0; $idx < $cnt; ++$idx)
{
$ary->put($esc);
$ary->getlines(Timeout => 1);
}
$ary->input_record_separator($irs);
}
sub initialScreen()
{
my $ary = $_[0];
if(($model eq "T6100F") || ($model eq "PV610F"))
{
&initialScreenSleep($ary);
}
elsif ($model eq "A24F-R2430")
{
&initialScreenGoble($ary);
}
}
sub selectVT100Interface()
{
my $ary = $_[0];
my $down = "\x1bOB";
$ary->print('');
sleep(1);
$ary->put($esc);
sleep(1);
$ary->put($down);
sleep(1);
}
sub getDrvStatus()
{
my $arrayname = $_[0];
my $arraypwd = $_[1];
my $eol = "\x1b\x5b";
my $rec;
my $idx = 0;
my $drvIdx = 0;
if($debug > 0)
{
print "telnet $arrayname\n";
}
my $ary = new Net::Telnet(Errmode => "return",
Timeout => 5,
Prompt => '/.*/') or
&makeExit("can't connect to array $arrayname");
$ary->open($arrayname) or &makeExit("can't connect");
if($debug > 0)
{
$ary->dump_log();
print "waiting for password prompt\n";
}
$ary->waitfor('/Password:.*/') or &makeExit("timed out");
$ary->print($arraypwd);
if($debug > 0)
{
print "initial password given\n";
}
&initialScreen($ary);
&selectVT100Interface($ary);
$ary->print(''); # Send a return to get to the main menu and re-login
$ary->waitfor('/(Enter)|(Input) Password:.*/') or &makeExit("timed out");
$ary->print($arraypwd);
$ary->waitfor('/.*view and edit .*vent logs.*/') or &makeExit("timed out");
$ary->buffer_empty(); # Empty the input buffer
$ary->put('D'); # Send a 'D' for the drives menu.
my $rs = $ary->rs($eol);
while(($drvIdx < $maxDrvCnt) && ($idx < 300))
{
if($debug > 0)
{
print "== $idx == $drvIdx ==\n";
print "== $rec ==\n";
}
$rec = $ary->getline() or &makeExit("timed out");
$_ = $rec;
if(($model eq "T6100F") || ($model eq "PV610F"))
{
# Parse the output looking for lines like:
# | 11| 715399|300MB| 1| ON-LINE|Seagate ST3750640AS |
if(/(\x0e.\x0f)?\s*(\d+)\x0e.\x0f\s*\w*\x0e.\x0f\s*\w*\x0e.\x0f\s*\w+\x0e.\x0f\s*([A-Z_\-]+)\s*\x0e.\x0f\s*.*\s*(\x0e.\x0f)?/)
{
if($debug > 0)
{
print "MATCH == $2 == $3 ==\n";
}
if($drvIdx + 1 == $2)
{
$drvStatus[$drvIdx] = $3;
++$drvIdx;
}
}
if(($drvIdx % 8) == 7)
{
$ary->put("\x0e"); # Send ^N for the next screen.
$ary->put("\x0c"); # Send a ^L to redraw the whole of the new screen.
}
++$idx;
}
elsif($model eq "A24F-R2430")
{
# Parse the output looking for lines like:
# | │ 2│ 2│ 1│ 953609│300MB│ 0│ON-LINE │Hitachi HDS721010KLA330 │
if(/(\x0e.\x0f\s*\x0e.\x0f)?\s*(\d+)\x0e.\x0f\s*\w*\x0e.\x0f\s*\w*\x0e.\x0f\s*\w*\x0e.\x0f\s*\w*\x0e.\x0f\s*\w+\x0e.\x0f\s*([A-Z_\-]+)\s*\x0e.\x0f\s*.*\s*(\x0e.\x0f)?/)
{
if($debug > 0)
{
print "MATCH == $2 == $3 ==\n";
}
if($drvIdx + 1 == $2)
{
$drvStatus[$drvIdx] = $3;
++$drvIdx;
}
}
if(($drvIdx % 8) == 7)
{
$ary->put("\x0e"); # Send ^N for the next screen.
}
++$idx;
}
}
$ary->rs($rs);
&initialScreen($ary);
$ary->close();
return($drvIdx);
}
## Main ##
# Parse command line options
Getopt::Long::config('no_ignore_case');
GetOptions (
"d|debug=i" => \$debug,
"e|expected=i" => \$expDrvCnt,
"h|help" => \$help,
"a|array=s" => \$arrayname,
"m|model=s" => \$model,
"p|password=s" => \$arraypwd
);
if(($model ne "T6100F") && ($model ne "PV610F") && ($model ne "A24F-R2430"))
{
$help = 1;
}
# Show usage and exit if appropriate
if($help)
{
&showUsage();
&makeExit("usage");
}
# Get status of the physical drives
if(($model eq "T6100F") || ($model eq "PV610F"))
{
$maxDrvCnt = 16;
}
elsif($model eq "A24F-R2430")
{
$maxDrvCnt = 24;
}
$drvCnt = &getDrvStatus($arrayname, $arraypwd);
if($debug > 1)
{
print("== $drvCnt ==\n");
}
for(my $idx = 0; $idx < $drvCnt; ++$idx)
{
$_ = $drvStatus[$idx];
if(m/ON-LINE/)
{
++$drvOkCnt;
}
}
# Decide if there is an error or all is OK.
if($expDrvCnt != $drvCnt)
{
$state = $statusTab{'CRITICAL'};
$mesg = "only $drvCnt/ $expDrvCnt physical drives found";
}
elsif($drvCnt != $drvOkCnt)
{
$state = $statusTab{'CRITICAL'};
$mesg = "only $drvOkCnt / $drvCnt physical drives on-line";
}
else
{
$state = $statusTab{'OK'};
$mesg = "$drvOkCnt / $drvCnt physical drives OK";
}
&makeExit($mesg);