From 280cf69bd50882cd6661afbe62ee4182f9e4e74b Mon Sep 17 00:00:00 2001 From: qgarnier Date: Wed, 16 Jul 2014 21:54:05 +0200 Subject: [PATCH] Refs #5077 Refs #5425 --- centreon/plugins/misc.pm | 2 +- .../server/sun/mgmt_cards/mode/showboards.pm | 117 ++++++++--- os/solaris/local/conf/prtdiag.conf | 24 ++- os/solaris/local/mode/lomv120.pm | 194 +++++++++--------- .../local/mode/lomv120components/fan.pm | 83 ++++++++ .../local/mode/lomv120components/psu.pm | 79 +++++++ os/solaris/local/mode/lomv120components/sf.pm | 83 ++++++++ .../local/mode/lomv120components/voltage.pm | 83 ++++++++ os/solaris/local/mode/prtdiag.pm | 3 +- storage/emc/clariion/mode/sp.pm | 186 ++++++++++++++--- .../emc/clariion/mode/spcomponents/battery.pm | 79 +++++++ storage/emc/clariion/mode/spcomponents/psu.pm | 5 +- 12 files changed, 761 insertions(+), 177 deletions(-) create mode 100644 os/solaris/local/mode/lomv120components/fan.pm create mode 100644 os/solaris/local/mode/lomv120components/psu.pm create mode 100644 os/solaris/local/mode/lomv120components/sf.pm create mode 100644 os/solaris/local/mode/lomv120components/voltage.pm create mode 100644 storage/emc/clariion/mode/spcomponents/battery.pm diff --git a/centreon/plugins/misc.pm b/centreon/plugins/misc.pm index 6a87b4e85..94b773c8a 100644 --- a/centreon/plugins/misc.pm +++ b/centreon/plugins/misc.pm @@ -136,7 +136,7 @@ sub execute { return ($stdout, $exit_code); } - if ($exit_code != 0) { + if ($exit_code != 0 && (!defined($options{no_errors}) || !defined($options{no_errors}->{$exit_code}))) { $stdout =~ s/\n/ - /g; $options{output}->output_add(severity => 'UNKNOWN', short_msg => "Command error: $stdout"); diff --git a/hardware/server/sun/mgmt_cards/mode/showboards.pm b/hardware/server/sun/mgmt_cards/mode/showboards.pm index 3ae24ecad..2c5244602 100644 --- a/hardware/server/sun/mgmt_cards/mode/showboards.pm +++ b/hardware/server/sun/mgmt_cards/mode/showboards.pm @@ -58,8 +58,13 @@ sub new { "memory" => { name => 'memory' }, "command-plink:s" => { name => 'command_plink', default => 'plink' }, "ssh" => { name => 'ssh' }, + "exclude:s" => { name => 'exclude' }, + "no-component:s" => { name => 'no_component' }, }); $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + $self->{components} = {}; + $self->{no_components} = undef; + return $self; } @@ -87,6 +92,14 @@ sub check_options { if (!defined($self->{option_results}->{ssh})) { require hardware::server::sun::mgmt_cards::lib::telnet; } + + if (defined($self->{option_results}->{no_component})) { + if ($self->{option_results}->{no_component} ne '') { + $self->{no_components} = $self->{option_results}->{no_component}; + } else { + $self->{no_components} = 'critical'; + } + } } sub telnet_shell_plateform { @@ -127,21 +140,6 @@ sub ssh_command { $self->{output}->display(); $self->{output}->exit(); } - if ($exit_code != 0) { - $stdout =~ s/\n/ - /g; - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Command error: $stdout"); - $self->{output}->display(); - $self->{output}->exit(); - } - - if ($stdout !~ /Slot/mi) { - $self->{output}->output_add(long_msg => $stdout); - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Command 'showboards' problems (see additional info)."); - $self->{output}->display(); - $self->{output}->exit(); - } return $stdout; } @@ -167,37 +165,45 @@ sub run { if (defined($self->{option_results}->{memory})) { $self->{statefile_cache}->read(statefile => 'cache_sun_mgmtcards_' . $self->{option_results}->{hostname} . '_' . $self->{mode}); - $self->{output}->output_add(severity => 'OK', - short_msg => "No new problems on system."); - } else { - $self->{output}->output_add(severity => 'OK', - short_msg => "No problems on system."); } + + #Slot Pwr Component Type State Status Domain + #---- --- -------------- ----- ------ ------ + #SSC0 On System Controller Main Passed - + #ID0 On Sun Fire 6800 Centerplane - OK - + #PS0 On A212 Power Supply - OK - + #PS1 On A212 Power Supply - OK - + #PS2 On A212 Power Supply - OK - + #PS3 On A212 Power Supply - OK - + #PS4 On A212 Power Supply - OK - + #PS5 On A212 Power Supply - OK - my $datas = {}; + $self->{output}->output_add(long_msg => "Checking slots"); + $self->{components}->{slot} = {name => 'slot', total => 0, skip => 0, known_error => 0}; + foreach (@lines) { chomp; - my $long_msg = $_; - $long_msg =~ s/\|/~/mg; - $self->{output}->output_add(long_msg => $long_msg); - my $id; - if (/([^\s]+?)\s+/) { - $id = $1; - } - my $status; - if (/\s+(Degraded|Failed|Not tested|Passed|OK|Under Test)\s+/i) { - $status = $1; - } - if (!defined($status) || $status eq '') { - next; - } + + my ($id, $status); + $id = $1 if (/([^\s]+?)\s+/); + $status = $1 if (/\s+(Degraded|Failed|Not tested|Passed|OK|Under Test)\s+/i); + next if (!defined($status) || $status eq ''); + next if ($self->check_exclude(section => 'slot', instance => $id)); + $self->{components}->{slot}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Slot '%s' status is %s.", + $id, $status) + ); if ($status =~ /^(Degraded|Failed)$/i) { if (defined($self->{option_results}->{memory})) { my $old_status = $self->{statefile_cache}->get(name => "slot_$id"); if (!defined($old_status) || $old_status ne $status) { $self->{output}->output_add(severity => 'CRITICAL', short_msg => "Slot '$id' status is '$status'"); + } else { + $self->{components}->{slot}->{known_error}++; } $datas->{"slot_$id"} = $status; } else { @@ -210,11 +216,45 @@ sub run { if (defined($self->{option_results}->{memory})) { $self->{statefile_cache}->write(data => $datas); } + + my $total_components = 0; + my $display_by_component = ''; + my $display_by_component_append = ''; + foreach my $comp (sort(keys %{$self->{components}})) { + # Skipping short msg when no components + next if ($self->{components}->{$comp}->{total} == 0 && $self->{components}->{$comp}->{skip} == 0); + $total_components += $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; + $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $self->{components}->{$comp}->{skip} . '/' . $self->{components}->{$comp}->{known_error} . ' ' . $self->{components}->{$comp}->{name}; + $display_by_component_append = ', '; + } + + $self->{output}->output_add(severity => 'OK', + short_msg => sprintf("All %s components [%s] are ok.", + $total_components, + $display_by_component) + ); + + if (defined($self->{option_results}->{no_component}) && $total_components == 0) { + $self->{output}->output_add(severity => $self->{no_components}, + short_msg => 'No components are checked.'); + } $self->{output}->display(); $self->{output}->exit(); } +sub check_exclude { + my ($self, %options) = @_; + + if (defined($options{instance})) { + if (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)$options{instance}(\s|,|$)/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{instance}.")); + return 1; + } + } + return 0; +} + 1; __END__ @@ -257,6 +297,15 @@ Plink command (default: plink). Use to set a path. Use ssh (with plink) instead of telnet. +=item B<--exclude> + +Exclude some slots (comma seperated list) (Example: --exclude=IDO,PS0) + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + =back =cut diff --git a/os/solaris/local/conf/prtdiag.conf b/os/solaris/local/conf/prtdiag.conf index c5acdac4e..7541e883b 100644 --- a/os/solaris/local/conf/prtdiag.conf +++ b/os/solaris/local/conf/prtdiag.conf @@ -135,6 +135,15 @@ checks.PSU.data_labels = Supply,Status checks.PSU.ok_condition = "%Status%" =~ m/^OK|NO_FAULT$/ checks.PSU.output_string = Power supply '%Supply%' status is '%Status%' +checks.IO.description = IO cards status +checks.IO.begin_match = ^=+\sIO Cards +checks.IO.end_match = ^= +checks.IO.skip_match = ^(-|Brd) +checks.IO.data_match = ^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+) +checks.IO.data_labels = Brd,Type,ID,Side,Slot,BusFreq,MaxBus,DevFunc,State +checks.IO.ok_condition = "%States%" eq "ok" +checks.IO.output_string = IO Card '%Type%/%ID%/%Side%/%Slot%' state is '%State%' + [Enterprise 150] system.match = ^System Configuration:.*Sun Ultra 1 SBus system.checks = Boards @@ -348,9 +357,10 @@ system.match = ^System Configuration:.*Sun Fire V240 system.checks = Fans,Leds,Temperatures,Voltages,Current,FRU checks.Fans.description = fans status -checks.Fans.begin_match = ^Fan Status: +checks.Fans.begin_match = ^Fan (Status|Speeds): checks.Fans.end_match = :$ -checks.Fans.data_match = ^(.*?\d+)\s+(\S+)\s+(\S+) +checks.Fans.skip_match = ^Location +checks.Fans.data_match = ^\s*(\S+)\s+(\S+)\s+(\S+) checks.Fans.data_labels = Location,Sensor,Status checks.Fans.ok_condition = "%Status%" eq "okay" checks.Fans.output_string = Fan '%Location%/%Sensor%' status is '%Status%' @@ -402,15 +412,7 @@ checks.FRU.output_string = FRU '%Location%' status is '%Status%' # OK Merethis [SunFire V440] system.match = ^System Configuration:.*Sun Fire V440 -system.checks = CPU,Fans,Leds,Temperatures,Voltages,Current,FRU - -checks.CPU.description = CPU status -checks.CPU.begin_match = ^=+ CPUs = -checks.CPU.end_match = ^$ -checks.CPU.data_match = ^\s*(\d+)\s+(?:.*?)\s+(\S+)\s+(\S+)\s*$ -checks.CPU.data_labels = CPU,Status,Location -checks.CPU.ok_condition = "%Status%" =~ m/^on-line|online$/ -checks.CPU.output_string = CPU%CPU% ('%Location%') status is '%Status%' +system.checks = Fans,Leds,Temperatures,Voltages,Current,FRU checks.Fans.description = fans status checks.Fans.begin_match = ^Fan Speeds: diff --git a/os/solaris/local/mode/lomv120.pm b/os/solaris/local/mode/lomv120.pm index b3d1ef27e..b933ef3f4 100644 --- a/os/solaris/local/mode/lomv120.pm +++ b/os/solaris/local/mode/lomv120.pm @@ -39,7 +39,10 @@ use base qw(centreon::plugins::mode); use strict; use warnings; -use centreon::plugins::misc; +use os::solaris::local::mode::lomv120components::fan; +use os::solaris::local::mode::lomv120components::psu; +use os::solaris::local::mode::lomv120components::voltage; +use os::solaris::local::mode::lomv120components::sf; sub new { my ($class, %options) = @_; @@ -58,121 +61,105 @@ sub new { "sudo" => { name => 'sudo' }, "command:s" => { name => 'command', default => 'lom' }, "command-path:s" => { name => 'command_path', default => '/usr/sbin' }, - "command-options:s" => { name => 'command_options', default => '-fpv 2>&1' }, + "command-options:s" => { name => 'command_options', default => '-fpv 2>&1'}, + "exclude:s" => { name => 'exclude' }, + "component:s" => { name => 'component', default => 'all' }, + "no-component:s" => { name => 'no_component' }, }); + $self->{components} = {}; + $self->{no_components} = undef; return $self; } sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); + + if (defined($self->{option_results}->{no_component})) { + if ($self->{option_results}->{no_component} ne '') { + $self->{no_components} = $self->{option_results}->{no_component}; + } else { + $self->{no_components} = 'critical'; + } + } +} + +sub component { + my ($self, %options) = @_; + + if ($self->{option_results}->{component} eq 'all') { + os::solaris::local::mode::lomv120components::fan::check($self); + os::solaris::local::mode::lomv120components::psu::check($self); + os::solaris::local::mode::lomv120components::voltage::check($self); + os::solaris::local::mode::lomv120components::sf::check($self); + } elsif ($self->{option_results}->{component} eq 'fan') { + os::solaris::local::mode::lomv120components::fan::check($self); + } elsif ($self->{option_results}->{component} eq 'psu') { + os::solaris::local::mode::lomv120components::psu::check($self); + } elsif ($self->{option_results}->{component} eq 'voltage') { + os::solaris::local::mode::lomv120components::voltage::check($self); + } elsif ($self->{option_results}->{component} eq 'sf') { + os::solaris::local::mode::lomv120components::sf::check($self); + } else { + $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); + $self->{output}->option_exit(); + } + + my $total_components = 0; + my $display_by_component = ''; + my $display_by_component_append = ''; + foreach my $comp (sort(keys %{$self->{components}})) { + # Skipping short msg when no components + next if ($self->{components}->{$comp}->{total} == 0 && $self->{components}->{$comp}->{skip} == 0); + $total_components += $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; + $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $self->{components}->{$comp}->{skip} . ' ' . $self->{components}->{$comp}->{name}; + $display_by_component_append = ', '; + } + + $self->{output}->output_add(severity => 'OK', + short_msg => sprintf("All %s components [%s] are ok.", + $total_components, + $display_by_component) + ); + + if (defined($self->{option_results}->{no_component}) && $total_components == 0) { + $self->{output}->output_add(severity => $self->{no_components}, + short_msg => 'No components are checked.'); + } } sub run { my ($self, %options) = @_; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, + ($self->{stdout}) = centreon::plugins::misc::execute(output => $self->{output}, options => $self->{option_results}, sudo => $self->{option_results}->{sudo}, command => $self->{option_results}->{command}, command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - my $long_msg = $stdout; - $long_msg =~ s/\|/~/mg; - $self->{output}->output_add(long_msg => $long_msg); - - $self->{output}->output_add(severity => 'OK', - short_msg => "No problems detected."); - - if ($stdout =~ /^Fans:(.*?):/ims) { - #Fans: - #1 FAULT speed 0% - #2 FAULT speed 0% - #3 OK speed 100% - #4 OK speed 100% - my @content = split(/\n/, $1); - shift @content; - pop @content; - foreach my $line (@content) { - next if ($line !~ /^\s*(\S+)\s+(\S+)/); - my ($fan_num, $status) = ($1, $2); - - if ($status !~ /OK/i) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => "Fan '$fan_num' status is '$status'"); - } - } - } - - if ($stdout =~ /^PSUs:(.*?):/ims) { - #PSUs: - #1 OK - my @content = split(/\n/, $1); - shift @content; - pop @content; - foreach my $line (@content) { - next if ($line !~ /^\s*(\S+)\s+(\S+)/); - my ($psu_num, $status) = ($1, $2); - - if ($status !~ /OK/i) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => "Psu '$psu_num' status is '$status'"); - } - } - } - - if ($stdout =~ /^Supply voltages:(.*?):/ims) { - #Supply voltages: - #1 5V status=ok - #2 3V3 status=ok - #3 +12V status=ok - my @content = split(/\n/, $1); - shift @content; - pop @content; - foreach my $line (@content) { - $line = centreon::plugins::misc::trim($line); - my @fields = split(/\s+/, $line); - - shift @fields; - my $field_status = pop(@fields); - $field_status =~ /status=(.*)/i; - my $status = $1; - my $name = join(' ', @fields); - if ($status !~ /OK/i) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => "Supply voltage '$name' status is '$status'"); - } - } - } - - if ($stdout =~ /^System status flags:(.*)/ims) { - #System status flags: - # 1 SCSI-Term status=ok - # 2 USB0 status=ok - # 3 USB1 status=ok - my @content = split(/\n/, $1); - shift @content; - pop @content; - foreach my $line (@content) { - $line = centreon::plugins::misc::trim($line); - my @fields = split(/\s+/, $line); - - shift @fields; - my $field_status = pop(@fields); - $field_status =~ /status=(.*)/i; - my $status = $1; - my $name = join(' ', @fields); - if ($status !~ /OK/i) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => "System '$name' flag status is '$status'"); - } - } - } + command_options => $self->{option_results}->{command_options}, + no_quit => 1); + $self->component(); $self->{output}->display(); $self->{output}->exit(); } +sub check_exclude { + my ($self, %options) = @_; + + if (defined($options{instance})) { + if (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)${options{section}}[^,]*#\Q$options{instance}\E#/) { + $self->{components}->{$options{section}}->{skip}++; + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + return 1; + } + } elsif (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)$options{section}(\s|,|$)/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + return 1; + } + return 0; +} + 1; __END__ @@ -193,7 +180,7 @@ Hostname to query (need --remote). =item B<--ssh-option> -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine" --ssh-option='-p=52"). +Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). =item B<--ssh-path> @@ -224,6 +211,21 @@ Command path (Default: '/usr/sbin'). Command options (Default: '-fpv 2>&1'). +=item B<--component> + +Which component to check (Default: 'all'). +Can be: 'fan', 'psu', 'voltage', 'sf'. + +=item B<--exclude> + +Exclude some parts (comma seperated list) (Example: --exclude=fan,sf) +Can also exclude specific instance: --exclude=fan#1#,sf + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + =back =cut diff --git a/os/solaris/local/mode/lomv120components/fan.pm b/os/solaris/local/mode/lomv120components/fan.pm new file mode 100644 index 000000000..76a720f53 --- /dev/null +++ b/os/solaris/local/mode/lomv120components/fan.pm @@ -0,0 +1,83 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# 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. +# +# 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, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package os::solaris::local::mode::lomv120components::fan; + +use strict; +use warnings; + +my %conditions = ( + 1 => ['^(?!(OK)$)' => 'CRITICAL'], +); + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_exclude(section => 'fan')); + + #Fans: + #1 FAULT speed 0% + #2 FAULT speed 0% + #3 OK speed 100% + #4 OK speed 100% + return if ($self->{stdout} !~ /^Fans:(.*?):/ims); + + my @content = split(/\n/, $1); + shift @content; + pop @content; + foreach my $line (@content) { + next if ($line !~ /^\s*(\S+)\s+(\S+)/); + my ($instance, $status) = ($1, $2); + + next if ($self->check_exclude(section => 'fan', instance => $instance)); + $self->{components}->{fan}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("fan '%s' status is %s.", + $instance, $status) + ); + foreach (keys %conditions) { + if ($status =~ /${$conditions{$_}}[0]/i) { + $self->{output}->output_add(severity => ${$conditions{$_}}[1], + short_msg => sprintf("fan '%s' status is %s", + $instance, $status)); + last; + } + } + } +} + +1; \ No newline at end of file diff --git a/os/solaris/local/mode/lomv120components/psu.pm b/os/solaris/local/mode/lomv120components/psu.pm new file mode 100644 index 000000000..37171d85f --- /dev/null +++ b/os/solaris/local/mode/lomv120components/psu.pm @@ -0,0 +1,79 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# 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. +# +# 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, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package os::solaris::local::mode::lomv120components::psu; + +use strict; +use warnings; + +my %conditions = ( + 1 => ['^(?!(OK)$)' => 'CRITICAL'], +); + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; + return if ($self->check_exclude(section => 'psu')); + + #PSUs: + #1 OK + return if ($self->{stdout} !~ /^PSUs:(((.*?)(?::|Supply))|(.*))/ims); + + my @content = split(/\n/, $1); + shift @content; + foreach my $line (@content) { + next if ($line !~ /^\s*(\S+)\s+(\S+)/); + my ($instance, $status) = ($1, $2); + + next if ($self->check_exclude(section => 'psu', instance => $instance)); + $self->{components}->{psu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("psu '%s' status is %s.", + $instance, $status) + ); + foreach (keys %conditions) { + if ($status =~ /${$conditions{$_}}[0]/i) { + $self->{output}->output_add(severity => ${$conditions{$_}}[1], + short_msg => sprintf("psu '%s' status is %s", + $instance, $status)); + last; + } + } + } +} + +1; \ No newline at end of file diff --git a/os/solaris/local/mode/lomv120components/sf.pm b/os/solaris/local/mode/lomv120components/sf.pm new file mode 100644 index 000000000..8e969f33c --- /dev/null +++ b/os/solaris/local/mode/lomv120components/sf.pm @@ -0,0 +1,83 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# 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. +# +# 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, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package os::solaris::local::mode::lomv120components::sf; + +use strict; +use warnings; +use centreon::plugins::misc; + +my %conditions = ( + 1 => ['^(?!(ok)$)' => 'CRITICAL'], +); + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking system flag"); + $self->{components}->{sf} = {name => 'system flag', total => 0, skip => 0}; + return if ($self->check_exclude(section => 'sf')); + + #System status flags: + # 1 SCSI-Term status=ok + # 2 USB0 status=ok + # 3 USB1 status=ok + return if ($self->{stdout} !~ /^System status flags:(.*)/ims); + + my @content = split(/\n/, $1); + shift @content; + foreach my $line (@content) { + $line = centreon::plugins::misc::trim($line); + next if ($line !~ /^\s*(\S+).*?status=(.*)/); + my ($instance, $status) = ($1, $2); + + next if ($self->check_exclude(section => 'sf', instance => $instance)); + $self->{components}->{sf}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("System flag '%s' status is %s.", + $instance, $status) + ); + foreach (keys %conditions) { + if ($status =~ /${$conditions{$_}}[0]/i) { + $self->{output}->output_add(severity => ${$conditions{$_}}[1], + short_msg => sprintf("System flag '%s' status is %s", + $instance, $status)); + last; + } + } + } +} + +1; \ No newline at end of file diff --git a/os/solaris/local/mode/lomv120components/voltage.pm b/os/solaris/local/mode/lomv120components/voltage.pm new file mode 100644 index 000000000..0cb70b6e8 --- /dev/null +++ b/os/solaris/local/mode/lomv120components/voltage.pm @@ -0,0 +1,83 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# 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. +# +# 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, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package os::solaris::local::mode::lomv120components::voltage; + +use strict; +use warnings; +use centreon::plugins::misc; + +my %conditions = ( + 1 => ['^(?!(ok)$)' => 'CRITICAL'], +); + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking supply voltages"); + $self->{components}->{voltage} = {name => 'voltages', total => 0, skip => 0}; + return if ($self->check_exclude(section => 'voltage')); + + #Supply voltages: + #1 5V status=ok + #2 3V3 status=ok + #3 +12V status=ok + return if ($self->{stdout} !~ /^Supply voltages:(((.*?)(?::|Status flag))|(.*))/ims); + + my @content = split(/\n/, $1); + shift @content; + foreach my $line (@content) { + $line = centreon::plugins::misc::trim($line); + next if ($line !~ /^\s*(\S+).*?status=(.*)/); + my ($instance, $status) = ($1, $2); + + next if ($self->check_exclude(section => 'voltage', instance => $instance)); + $self->{components}->{voltage}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Supply voltage '%s' status is %s.", + $instance, $status) + ); + foreach (keys %conditions) { + if ($status =~ /${$conditions{$_}}[0]/i) { + $self->{output}->output_add(severity => ${$conditions{$_}}[1], + short_msg => sprintf("Supply voltage '%s' status is %s", + $instance, $status)); + last; + } + } + } +} + +1; \ No newline at end of file diff --git a/os/solaris/local/mode/prtdiag.pm b/os/solaris/local/mode/prtdiag.pm index abb5e6035..d33be770f 100644 --- a/os/solaris/local/mode/prtdiag.pm +++ b/os/solaris/local/mode/prtdiag.pm @@ -87,7 +87,8 @@ sub prtdiag { sudo => $self->{option_results}->{sudo}, command => $self->{option_results}->{command}, command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); + command_options => $self->{option_results}->{command_options}, + no_errors => { 1 => 1 }); my @diag = split (/\n/, $stdout); diff --git a/storage/emc/clariion/mode/sp.pm b/storage/emc/clariion/mode/sp.pm index 1973075f3..ff34f6150 100644 --- a/storage/emc/clariion/mode/sp.pm +++ b/storage/emc/clariion/mode/sp.pm @@ -33,42 +33,168 @@ # #################################################################################### -package storage::emc::clariion::mode::spcomponents::sp; +package storage::emc::clariion::mode::sp; + +use base qw(centreon::plugins::mode); use strict; use warnings; +use centreon::plugins::misc; +use storage::emc::clariion::mode::spcomponents::fan; +use storage::emc::clariion::mode::spcomponents::lcc; +use storage::emc::clariion::mode::spcomponents::psu; +use storage::emc::clariion::mode::spcomponents::battery; +use storage::emc::clariion::mode::spcomponents::memory; +use storage::emc::clariion::mode::spcomponents::cpu; +use storage::emc::clariion::mode::spcomponents::iomodule; +use storage::emc::clariion::mode::spcomponents::cable; +use storage::emc::clariion::mode::spcomponents::sp; -my %conditions = ( - 1 => ['^(?!(Present|Valid)$)' => 'CRITICAL'], -); - -sub check { - my ($self) = @_; - - $self->{output}->output_add(long_msg => "Checking sp"); - $self->{components}->{sp} = {name => 'sp', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'sp')); +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; - # SP A State: Present - while ($self->{response} =~ /^SP\s+(\S+)\s+State:\s+(.*)$/mgi) { - my $instance = $1; - my $state = $2; - - next if ($self->check_exclude(section => 'sp', instance => $instance)); - $self->{components}->{sp}->{total}++; - - $self->{output}->output_add(long_msg => sprintf("sp '%s' state is %s.", - $instance, $state) - ); - foreach (keys %conditions) { - if ($state =~ /${$conditions{$_}}[0]/i) { - $self->{output}->output_add(severity => ${$conditions{$_}}[1], - short_msg => sprintf("sp '%s' state is %s", - $instance, $state)); - last; - } + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "exclude:s" => { name => 'exclude' }, + "component:s" => { name => 'component', default => 'all' }, + "no-component:s" => { name => 'no_component' }, + }); + + $self->{components} = {}; + $self->{no_components} = undef; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (defined($self->{option_results}->{no_component})) { + if ($self->{option_results}->{no_component} ne '') { + $self->{no_components} = $self->{option_results}->{no_component}; + } else { + $self->{no_components} = 'critical'; } } } -1; \ No newline at end of file +sub component { + my ($self, %options) = @_; + + if ($self->{option_results}->{component} eq 'all') { + storage::emc::clariion::mode::spcomponents::fan::check($self); + storage::emc::clariion::mode::spcomponents::lcc::check($self); + storage::emc::clariion::mode::spcomponents::psu::check($self); + storage::emc::clariion::mode::spcomponents::battery::check($self); + storage::emc::clariion::mode::spcomponents::cable::check($self); + storage::emc::clariion::mode::spcomponents::iomodule::check($self); + storage::emc::clariion::mode::spcomponents::memory::check($self); + storage::emc::clariion::mode::spcomponents::cpu::check($self); + storage::emc::clariion::mode::spcomponents::sp::check($self); + } elsif ($self->{option_results}->{component} eq 'sp') { + storage::emc::clariion::mode::spcomponents::sp::check($self); + } elsif ($self->{option_results}->{component} eq 'fan') { + storage::emc::clariion::mode::spcomponents::fan::check($self); + } elsif ($self->{option_results}->{component} eq 'lcc') { + storage::emc::clariion::mode::spcomponents::lcc::check($self); + } elsif ($self->{option_results}->{component} eq 'psu') { + storage::emc::clariion::mode::spcomponents::psu::check($self); + } elsif ($self->{option_results}->{component} eq 'battery') { + storage::emc::clariion::mode::spcomponents::psu::check($self); + } elsif ($self->{option_results}->{component} eq 'memory') { + storage::emc::clariion::mode::spcomponents::memory::check($self); + } elsif ($self->{option_results}->{component} eq 'cpu') { + storage::emc::clariion::mode::spcomponents::cpu::check($self); + } elsif ($self->{option_results}->{component} eq 'io') { + storage::emc::clariion::mode::spcomponents::iomodule::check($self); + } elsif ($self->{option_results}->{component} eq 'cable') { + storage::emc::clariion::mode::spcomponents::cable::check($self); + } else { + $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); + $self->{output}->option_exit(); + } + + my $total_components = 0; + my $display_by_component = ''; + my $display_by_component_append = ''; + foreach my $comp (sort(keys %{$self->{components}})) { + # Skipping short msg when no components + next if ($self->{components}->{$comp}->{total} == 0 && $self->{components}->{$comp}->{skip} == 0); + $total_components += $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; + $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $self->{components}->{$comp}->{skip} . ' ' . $self->{components}->{$comp}->{name}; + $display_by_component_append = ', '; + } + + $self->{output}->output_add(severity => 'OK', + short_msg => sprintf("All %s components [%s] are ok.", + $total_components, + $display_by_component) + ); + + if (defined($self->{option_results}->{no_component}) && $total_components == 0) { + $self->{output}->output_add(severity => $self->{no_components}, + short_msg => 'No components are checked.'); + } +} + +sub run { + my ($self, %options) = @_; + my $clariion = $options{custom}; + + $self->{response} = $clariion->execute_command(cmd => 'getcrus -all'); + chomp $self->{response}; + + $self->component(); + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub check_exclude { + my ($self, %options) = @_; + + if (defined($options{instance})) { + if (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)${options{section}}[^,]*#\Q$options{instance}\E#/) { + $self->{components}->{$options{section}}->{skip}++; + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + return 1; + } + } elsif (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)$options{section}(\s|,|$)/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + return 1; + } + return 0; +} + +1; + +__END__ + +=head1 MODE + +Check status of storage processor. + +=over 8 + +=item B<--component> + +Which component to check (Default: 'all'). +Can be: 'cpu', 'psu', 'pc', 'fan', 'network', 'temperature', 'storage', 'battery'. + +=item B<--exclude> + +Exclude some parts (comma seperated list) (Example: --exclude=fan,lcc) +Can also exclude specific instance: --exclude=fan#1.2#,lcc + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=back + +=cut \ No newline at end of file diff --git a/storage/emc/clariion/mode/spcomponents/battery.pm b/storage/emc/clariion/mode/spcomponents/battery.pm new file mode 100644 index 000000000..7ec9d4d77 --- /dev/null +++ b/storage/emc/clariion/mode/spcomponents/battery.pm @@ -0,0 +1,79 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# 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. +# +# 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, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package storage::emc::clariion::mode::spcomponents::battery; + +use strict; +use warnings; + +my %conditions = ( + 1 => ['^Not Ready$' => 'WARNING'], + 2 => ['^(?!(Present|Valid)$)' => 'CRITICAL'], +); + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking batteries"); + $self->{components}->{battery} = {name => 'battery', total => 0, skip => 0}; + return if ($self->check_exclude(section => 'battery')); + + # SPS means = Standby Power Supply + + # Enclosure SPE SPS A State: Present + while ($self->{response} =~ /^(?:Bus\s+(\d+)\s+){0,1}Enclosure\s+(\S+)\s+(SPS)\s+(\S+)\s+State:\s+(.*)$/mgi) { + my ($state, $instance) = ($5, "$2.$3.$4"); + if (defined($1)) { + $instance = "$1.$2.$3.$4"; + } + + next if ($self->check_exclude(section => 'battery', instance => $instance)); + $self->{components}->{battery}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Battery '%s' state is %s.", + $instance, $state) + ); + foreach (keys %conditions) { + if ($state =~ /${$conditions{$_}}[0]/i) { + $self->{output}->output_add(severity => ${$conditions{$_}}[1], + short_msg => sprintf("Battery '%s' state is %s", + $instance, $state)); + last; + } + } + } +} + +1; \ No newline at end of file diff --git a/storage/emc/clariion/mode/spcomponents/psu.pm b/storage/emc/clariion/mode/spcomponents/psu.pm index 9427bef96..7ba98a7f5 100644 --- a/storage/emc/clariion/mode/spcomponents/psu.pm +++ b/storage/emc/clariion/mode/spcomponents/psu.pm @@ -49,12 +49,9 @@ sub check { $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; return if ($self->check_exclude(section => 'psu')); - # SPS means = Standby Power Supply - # Enclosure SPE Power A0 State: Present - # Enclosure SPE SPS A State: Present # Bus 0 Enclosure 0 Power A State: Present - while ($self->{response} =~ /^(?:Bus\s+(\d+)\s+){0,1}Enclosure\s+(\S+)\s+(Power|SPS)\s+(\S+)\s+State:\s+(.*)$/mgi) { + while ($self->{response} =~ /^(?:Bus\s+(\d+)\s+){0,1}Enclosure\s+(\S+)\s+(Power)\s+(\S+)\s+State:\s+(.*)$/mgi) { my ($state, $instance) = ($5, "$2.$3.$4"); if (defined($1)) { $instance = "$1.$2.$3.$4";