Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
server:monitoring
monitoring-plugins-dothill
check_dothill
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File check_dothill of Package monitoring-plugins-dothill
#!/usr/bin/perl # nagios: -epn # # check_dothill - nagios plugin # # Copyright (C) 2012, SUSE Linux Products GmbH # Author: Lars Vogdt <lars@linux-schulserver.de> # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of the Novell nor the names of its contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # use strict; use warnings; use Getopt::Long; use Net::Telnet; use Pod::Usage; our $conf={ VERSION => '0.1.0', PROGNAME => 'check_dothill', config => "/etc/check_dothill.conf", debug => 0, logfile => '/var/log/check_dothill.log', loglevel => 1, host => 'localhost', username => 'manage', password => 'manage', timeout => 60, no_sensors => 0, no_controllers=>0, no_vdisks=>0, no_ports=>0, no_disks=>0, }; our %ERRORS = ( 'OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3, 'DEPENDENT' => 4, ); my $print_help = 0; my $exitcode = 0; ####################################################################### ## Function Area ####################################################################### sub unknown_option { print "Problem with options, try to -h to get full help about all options \n"; exit "$ERRORS{'UNKNOWN'}"; } sub check_vdisks($){ my ($conf)=@_; my $output=''; my $perfdata=''; my $exitcode='OK'; my $vdisk_count=0; # # LOGIN # dump_log($conf->{'logfile'}) my $t = new Net::Telnet ( -Timeout => $conf->{'timeout'}, -Errmode => 'return', -Prompt => '/\# /') or return("Could not open socket",'CRITICAL'); my $ret = $t->open($conf->{'host'}) or return("Could not connect to $conf->{'host'}",'CRITICAL'); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Connected - waiting for password prompt\n"; } $ret = $t->login($conf->{'username'}, $conf->{'password'}) or return("Could not login to $conf->{'host'}",'CRITICAL'); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Logged in - waiting for prompt\n"; } # # SHOW VDISKS # my @lines=$t->cmd("show vdisks\n"); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Showing vdisks\n"; } foreach (@lines){ if($conf->{'debug'}){ print STDERR "$_\n"; } next if (/^ /); next if (/^--/); next if (/^Success:/); next if (/^\s*$/); next if (/^Name /); my ($name,$size,$free,$Own,$pref,$raid,$disks,$spr,$chk,$status,$jobs,$jobar,$serial,$spin_down,$spin_down_delay)=split(/\s+/,$_); if ($_ =~ /Crit/){ $output.="vdisk error on $name; "; $exitcode='CRITICAL'; } $vdisk_count++; $perfdata.="'$name'=$size;$free; "; } # # EXIT # $output.="$vdisk_count vdisks defined; "; $t->cmd("exit"); $t->close; return("$output","$exitcode","$perfdata"); } sub check_controllers($){ my ($conf)=@_; my $output=''; my $exitcode='OK'; # # LOGIN # my $t = new Net::Telnet ( -Timeout => $conf->{'timeout'}, -Errmode => 'return', -Prompt => '/\# /') or return("Could not open socket",'CRITICAL'); my $ret = $t->open($conf->{'host'}) or return("Could not connect to $conf->{'host'}",'CRITICAL'); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Connected - waiting for password prompt\n"; } $ret = $t->login($conf->{'username'}, $conf->{'password'}) or return("Could not login to $conf->{'host'}",'CRITICAL'); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Logged in - waiting for prompt\n"; } # # SHOW CONTROLLERS # my @lines = $t->cmd("show controllers\n"); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Showing controllers\n"; } my %controller_info; my $controller_id; foreach my $line (@lines){ if($conf->{'debug'}){ print STDERR "LINE: $line\n"; } next if ($line =~ /^ /); if ($line =~ /Controller ID: (.*)/){ $controller_id=$1; $controller_info{$controller_id}->{'id'}="$controller_id"; } elsif ($line =~ /Serial Number: (.*)/){ $controller_info{$controller_id}->{'serial'}=$1; } elsif ($line =~ /Status: (.*)/){ $controller_info{$controller_id}->{'status'}=$1; } elsif ($line =~ /Failed Over: (.*)/){ $controller_info{$controller_id}->{'failed_over'}=$1; } elsif ($line =~ /Position: (.*)/){ $controller_info{$controller_id}->{'position'}=$1; } } foreach my $id (sort(keys(%controller_info))){ if ($controller_info{$id}->{'status'} !~ /Operational/){ $output.="Controller $id (Serial: ".$controller_info{$id}->{'serial'}."; Position: ".$controller_info{$id}->{'position'}.") is in state ".$controller_info{$id}->{'status'}."; "; $exitcode='CRITICAL'; } elsif ($controller_info{$id}->{'failed_over'} !~ /No/){ $output.="Controller $id (Serial: ".$controller_info{$id}->{'serial'}."; Position: ".$controller_info{$id}->{'position'}.") state ".$controller_info{$id}->{'status'}." is running in fail over mode; "; $exitcode='CRITICAL'; } else { $output.="Controller $id (Serial: ".$controller_info{$id}->{'serial'}."; Position: ".$controller_info{$id}->{'position'}.") state OK; "; } } return("$output","$exitcode"); } sub check_disks($){ my ($conf)=@_; my $output='OK'; my $exitcode='OK'; # my $disk_count=0; # my $perfdata=''; # my ($location,$serial,$vendor,$rev,$spare_type,$used_as,$type,$size,$rate,$health,$health_reason)=''; # # LOGIN # my $t = new Net::Telnet ( -Timeout => $conf->{'timeout'}, -Errmode => 'return', -Prompt => '/\# /') or return("Could not open socket",'CRITICAL'); my $ret = $t->open($conf->{'host'}) or return("Could not connect to $conf->{'host'}",'CRITICAL'); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Connected - waiting for password prompt\n"; } $ret = $t->login($conf->{'username'}, $conf->{'password'}) or return("Could not login to $conf->{'host'}",'CRITICAL'); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Logged in - waiting for prompt\n"; } # # SHOW DISKS # my @lines = $t->cmd("show disks\n"); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Showing disks\n"; } foreach my $line (@lines){ if($conf->{'debug'}){ print STDERR "LINE: $line\n"; } next if ($line =~ /^ /); next if ($line =~ /^--/); next if ($line =~ /^Success:/); next if ($line =~ /^Info:/); next if ($line =~ /^\s*Size/); next if ($line =~ /^\s*$/); next if ($line =~ /^Location/); if ($line !~ /OK/){ $output.="disk critical: $line"; $exitcode='CRITICAL'; } } # # EXIT # $t->cmd("exit"); $t->close; return("$output","$exitcode"); } sub check_ports($){ my ($conf)=@_; my $output='OK'; my $exitcode='OK'; my $portcount=0; # # LOGIN # my $t = new Net::Telnet ( -Timeout => $conf->{'timeout'}, -Errmode => 'return', -Prompt => '/\# /') or return("Could not open socket",'CRITICAL'); my $ret = $t->open($conf->{'host'}) or return("Could not connect to $conf->{'host'}",'CRITICAL'); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Connected - waiting for password prompt\n"; } $ret = $t->login($conf->{'username'}, $conf->{'password'}) or return("Could not login to $conf->{'host'}",'CRITICAL'); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Logged in - waiting for prompt\n"; } # # SHOW PORTS # my @ports=$t->cmd("show ports\n"); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Showing ports\n"; } foreach (@ports){ if($conf->{'debug'}){ print STDERR "$_\n"; } next if (/^ /); next if (/^--/); next if (/^Success:/); next if (/^\s*$/); next if (/^\sPorts/); my ($port,$media,$targetid,$status,$speeda,$speedc)=split(/\s+/,$_); if ($_ =~ /Disconnected/){ $output.="Port disconnected: $port; "; $exitcode='CRITICAL'; } elsif ($_ =~ /Up/){ $portcount++; } } $output="$portcount Ports are in state 'Up'; "; # # EXIT # $t->cmd("exit"); $t->close; return("$output","$exitcode"); } sub trim($){ my ($string)=@_; $string =~ s/^\s+//; $string =~ s/\s+$//; return $string; } sub check_sensors($){ my ($conf)=@_; my $output=''; my $master_output=''; my $exitcode='OK'; my $perfdata=''; # # LOGIN # my $t = new Net::Telnet ( -Timeout => $conf->{'timeout'}, -Errmode => 'return', -Prompt => '/\# /') or return("Could not open socket",'CRITICAL'); my $ret = $t->open($conf->{'host'}) or return("Could not connect to $conf->{'host'}",'CRITICAL'); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Connected - waiting for password prompt\n"; } $ret = $t->login($conf->{'username'}, $conf->{'password'}) or return("Could not login to $conf->{'host'}",'CRITICAL'); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Logged in - waiting for prompt\n"; } # # SHOW SENSORS # my @lines = $t->cmd("show sensor-status\n"); if($conf->{'debug'}){ $t->dump_log($conf->{'logfile'}); print STDERR "Showing sensor-status\n"; } foreach my $line (@lines){ if($conf->{'debug'}){ print STDERR "LINE: $line\n"; } next if ($line =~ /^ /); next if ($line =~ /^--/); next if ($line =~ /^Success/); next if ($line =~ /^Sensor/); if ($line =~ /^Temperature Loc: (.*)\s+(\d+) C\s+(.*)/){ my $loc=trim($1); my $state=trim($3); my $temp=trim($2); $output.="Temp $loc $state: $temp C; "; $perfdata.="'temp $loc'=$temp; "; } elsif ($line =~ /On-Board Temperature (.*)\s+(\d+) C\s+(.*)/){ my $loc=trim($1); my $state=trim($3); my $temp=trim($2); $output.="On-Board Temp $loc $state: $temp C; "; $perfdata.="'temp $loc'=$temp; "; } elsif ($line =~ /Disk Controller (.*)\s+(\d+) C\s+(.*)/){ my $loc=trim($1); my $state=trim($3); my $temp=trim($2); $output.="Disk Controller Temp $loc $state: $temp C; "; $perfdata.="'disk contr. $loc'=$temp; "; } elsif ($line =~ /Memory Controller (.*)\s+(\d+) C\s+(.*)/){ my $loc=trim($1); my $state=trim($3); my $temp=trim($2); $output.="Memory Controller Temp $loc $state: $temp C; "; $perfdata.="'mem contr. $loc'=$temp; "; } # Overall Unit Status OK OK elsif ($line =~ /Overall Unit Status\s+(\w+)\s+(\w+)/){ my $state=trim($1); if ($state !~ /OK/){ $exitcode='CRITICAL'; } $master_output="Overall Unit Status $state;"; } } $output="$master_output $output"; # # EXIT # $t->cmd("exit"); $t->close; return("$output","$exitcode", "$perfdata"); } ####################################################################### ## Main Area ####################################################################### my $number_of_options = @ARGV; pod2usage ( -exitstatus => 0, -verbose => 2, # 2 to print full pod ) if $number_of_options == 0; Getopt::Long::Configure('bundling'); GetOptions( "h|help" => \$print_help, "c|config=s" => \$conf->{'config'}, "d|debug" => \$conf->{'debug'}, "logfile=s" => \$conf->{'logfile'}, "loglevel=i" => \$conf->{'loglevel'}, "t|timeout=i" => \$conf->{'timeout'}, "u|username=s" => \$conf->{'username'}, "p|password=s" => \$conf->{'password'}, "H|host=s" => \$conf->{'host'}, "S|no-sensors" => \$conf->{'no_sensors'}, "C|no-controllers" => \$conf->{'no_controllers'}, "V|no-vdisks" => \$conf->{'no_vdisks'}, "P|no-ports" => \$conf->{'no_ports'}, "D|no-disks" => \$conf->{'no_disks'}, ) or (unknown_option); pod2usage ( -exitstatus => 0, -verbose => 2, # 2 to print full pod ) if $print_help; if ($conf->{'debug'}){ use Data::Dumper; print STDERR "Config:\n".Data::Dumper->Dump([$conf])."\n"; } # Just in case of problems, let's not hang Nagios $SIG{'ALRM'} = sub { print "UNKNOWN - Plugin timed out\n"; exit $ERRORS{'UNKNOWN'}; }; alarm($conf->{'timeout'}); my $exit='OK'; my $output=''; my $perfdata=''; if (! $conf->{'no_sensors'}){ # sensor output my ($sensor_output,$sensor_exit,$sensor_perfdata)=check_sensors($conf); if ($sensor_exit !~ /OK/){ $exit=$sensor_exit; } $output.=$sensor_output; $perfdata.=$sensor_perfdata; } if (! $conf->{'no_controllers'}){ # check controllers my ($controller_output,$controller_exit)=check_controllers($conf); if ($controller_exit !~ /OK/){ $exit=$controller_exit; } $output.=$controller_output; } if (! $conf->{'no_vdisks'}){ # check vdisks my ($vdisk_output,$vdisk_exit,$vdisk_perfdata)=check_vdisks($conf); if ($vdisk_exit !~ /OK/){ $exit=$vdisk_exit; } $output.=$vdisk_output; } if (! $conf->{'no_ports'}){ # check ports my ($portoutput,$portexit)=check_ports($conf); if ($portexit !~ /OK/){ $exit=$portexit; } $output.=$portoutput; } #if (! $conf->{'no_disks'}){ # disk output #my ($disk_output,$disk_exit)=check_disks($conf); #if ($disk_exit !~ /OK/){ # $exit=$disk_exit; #} #$output.=$disk_output; #} print "$output | $perfdata\n"; alarm(0); exit $ERRORS{$exit} __END__ =head1 Check Dothill RAID Array Check Dot Hill Revolution Storage Arrays. =head1 SYNOPSIS ./check_dothill -H <hostname> -u <username> -p <password> <OPTIONS> Options: -c <file> | --config <file> -H <host> | --host <host> -u <username> | --username <username> -p <password> | --password <password> -S | --no-sensors -C | --no-controllers -V | --no-vdisks -P | --no-ports -D | --no-disks | --logfile <file> | --loglevel <int> -h | --help -d | --debug =head1 OPTIONS =over 8 =item B<--config> F<file> Use configfile F<file> to get needed options. =item B<--host> F<HOST> The hostname or IP address. =item B<--username> F<USERNAME> The username to login to the console. =item B<--password> F<PASSWORD> The password to login to the console. =item B<--no-sensors> Disable sensor check. =item B<--no-controllers> Disable controller check. =item B<--no-vdisks> Disable virtual disk check. =item B<--no-ports> Disable port check. =item B<--no-disks> Disable phisical disk check. =back =head1 DESCRIPTION Use check_dothill if you want to get some information about your Dot Hill Revolution Storage Arrays. The pluing uses a Telnet connection and the given username/password pair to login and execute some commands. Afterwards the output is parsed, condensed and re-arranged for a Nagios Plugin compatible output. =head1 AUTHORS =over 8 =item Lars Vogdt <lars@linux-schulserver.de> 2012 =back =cut
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor