diff --git a/centreon-plugins/hardware/server/cisco/ucs/mode/components/fan.pm b/centreon-plugins/hardware/server/cisco/ucs/mode/components/fan.pm index f595e22db..dd23605ae 100644 --- a/centreon-plugins/hardware/server/cisco/ucs/mode/components/fan.pm +++ b/centreon-plugins/hardware/server/cisco/ucs/mode/components/fan.pm @@ -44,42 +44,42 @@ sub check { # In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' $self->{output}->output_add(long_msg => "Checking fans"); - $self->{components}->{fan} = {name => 'fans', total => 0}; - return if ($self->check_exclude('fan')); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_exclude(section => 'fan')); my $oid_cucsEquipmentFanPresence = '.1.3.6.1.4.1.9.9.719.1.15.12.1.13'; my $oid_cucsEquipmentFanOperState = '.1.3.6.1.4.1.9.9.719.1.15.12.1.9'; my $oid_cucsEquipmentFanDn = '.1.3.6.1.4.1.9.9.719.1.15.12.1.2'; - my $result = $self->{snmp}->get_table(oid => $oid_cucsEquipmentFanPresence); - my @get_oids = (); - my @oids_end = (); - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + my $result = $self->{snmp}->get_multiple_table(oids => [ + { oid => $oid_cucsEquipmentFanPresence }, + { oid => $oid_cucsEquipmentFanOperState }, + { oid => $oid_cucsEquipmentFanDn }, + ] + ); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsEquipmentFanPresence}})) { # index $key =~ /\.(\d+)$/; - my $oid_end = $1; + my $fan_index = $1; + my $fan_dn = $result->{$oid_cucsEquipmentFanDn}->{$oid_cucsEquipmentFanDn . '.' . $fan_index}; + my $fan_operstate = defined($result->{$oid_cucsEquipmentFanOperState}->{$oid_cucsEquipmentFanOperState . '.' . $fan_index}) ? + $result->{$oid_cucsEquipmentFanOperState}->{$oid_cucsEquipmentFanOperState . '.' . $fan_index} : 0; # unknown + my $fan_presence = defined($result->{$oid_cucsEquipmentFanPresence}->{$oid_cucsEquipmentFanPresence . '.' . $fan_index}) ? + $result->{$oid_cucsEquipmentFanPresence}->{$oid_cucsEquipmentFanPresence . '.' . $fan_index} : 0; + + next if ($self->absent_problem(section => 'fan', instance => $fan_dn)); + next if ($self->check_exclude(section => 'fan', instance => $fan_dn)); - if (${$presence{$result->{$key}}}[1] ne 'OK') { - $self->{components}->{fan}->{total}++; - $self->{output}->output_add(severity => ${$presence{$result->{$key}}}[1], - short_msg => sprintf("fan index '%s' presence is: '%s'", - $oid_end, ${$presence{$result->{$key}}}[0]) + if (${$presence{$fan_presence}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$presence{$fan_presence}}[1], + short_msg => sprintf("fan '%s' presence is: '%s'", + $fan_dn, ${$presence{$fan_presence}}[0]) ); + next; } - push @oids_end, $oid_end; - push @get_oids, $oid_cucsEquipmentFanOperState . "." . $oid_end, $oid_cucsEquipmentFanDn . "." . $oid_end; - } - return if (scalar(@get_oids) <= 0); - - my $result2 = $self->{snmp}->get_leef(oids => \@get_oids); - foreach (@oids_end) { - my ($fan_index) = $_; - my $fan_dn = $result2->{$oid_cucsEquipmentFanDn . '.' . $_}; - my $fan_operstate = $result2->{$oid_cucsEquipmentFanOperState . '.' . $_}; - my $fan_presence = $result->{$oid_cucsEquipmentFanPresence . '.' . $_}; - $self->{components}->{fan}->{total}++; + $self->{output}->output_add(long_msg => sprintf("fan '%s' state is '%s' [presence: %s].", $fan_dn, ${$operability{$fan_operstate}}[0], ${$presence{$fan_presence}}[0] diff --git a/centreon-plugins/hardware/server/cisco/ucs/mode/components/iocard.pm b/centreon-plugins/hardware/server/cisco/ucs/mode/components/iocard.pm new file mode 100644 index 000000000..9f585a2d9 --- /dev/null +++ b/centreon-plugins/hardware/server/cisco/ucs/mode/components/iocard.pm @@ -0,0 +1,97 @@ +################################################################################ +# 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 hardware::server::cisco::ucs::mode::components::iocard; + +use strict; +use warnings; +use hardware::server::cisco::ucs::mode::components::resources qw(%presence %operability); + +sub check { + my ($self) = @_; + + # In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' + $self->{output}->output_add(long_msg => "Checking io cards"); + $self->{components}->{iocard} = {name => 'io cards', total => 0, skip => 0}; + return if ($self->check_exclude(section => 'iocard')); + + my $oid_cucsEquipmentIOCardPresence = '.1.3.6.1.4.1.9.9.719.1.15.30.1.31'; + my $oid_cucsEquipmentIOCardOperState = '.1.3.6.1.4.1.9.9.719.1.15.30.1.25'; + my $oid_cucsEquipmentIOCardDn = '.1.3.6.1.4.1.9.9.719.1.15.30.1.2'; + + my $result = $self->{snmp}->get_multiple_table(oids => [ + { oid => $oid_cucsEquipmentIOCardPresence }, + { oid => $oid_cucsEquipmentIOCardOperState }, + { oid => $oid_cucsEquipmentIOCardDn }, + ] + ); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsEquipmentIOCardPresence}})) { + # index + $key =~ /\.(\d+)$/; + my $iocard_index = $1; + my $iocard_dn = $result->{$oid_cucsEquipmentIOCardDn}->{$oid_cucsEquipmentIOCardDn . '.' . $iocard_index}; + my $iocard_operstate = defined($result->{$oid_cucsEquipmentIOCardOperState}->{$oid_cucsEquipmentIOCardOperState . '.' . $iocard_index}) ? + $result->{$oid_cucsEquipmentIOCardOperState}->{$oid_cucsEquipmentIOCardOperState . '.' . $iocard_index} : 0; # unknown + my $iocard_presence = defined($result->{$oid_cucsEquipmentIOCardPresence}->{$oid_cucsEquipmentIOCardPresence . '.' . $iocard_index}) ? + $result->{$oid_cucsEquipmentIOCardPresence}->{$oid_cucsEquipmentIOCardPresence . '.' . $iocard_index} : 0; + + next if ($self->absent_problem(section => 'iocard', instance => $iocard_dn)); + next if ($self->check_exclude(section => 'iocard', instance => $iocard_dn)); + + if (${$presence{$iocard_presence}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$presence{$iocard_presence}}[1], + short_msg => sprintf("IO cards '%s' presence is: '%s'", + $iocard_dn, ${$presence{$iocard_presence}}[0]) + ); + next; + } + + $self->{components}->{iocard}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("IO cards '%s' state is '%s' [presence: %s].", + $iocard_dn, ${$operability{$iocard_operstate}}[0], + ${$presence{$iocard_presence}}[0] + )); + if (${$operability{$iocard_operstate}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$operability{$iocard_operstate}}[1], + short_msg => sprintf("IO cards '%s' state is '%s'.", + $iocard_dn, ${$operability{$iocard_operstate}}[0] + ) + ); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/hardware/server/cisco/ucs/mode/components/psu.pm b/centreon-plugins/hardware/server/cisco/ucs/mode/components/psu.pm new file mode 100644 index 000000000..dd6162299 --- /dev/null +++ b/centreon-plugins/hardware/server/cisco/ucs/mode/components/psu.pm @@ -0,0 +1,97 @@ +################################################################################ +# 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 hardware::server::cisco::ucs::mode::components::psu; + +use strict; +use warnings; +use hardware::server::cisco::ucs::mode::components::resources qw(%presence %operability); + +sub check { + my ($self) = @_; + + # In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' + $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')); + + my $oid_cucsEquipmentPsuPresence = '.1.3.6.1.4.1.9.9.719.1.15.56.1.11'; + my $oid_cucsEquipmentPsuOperState = '.1.3.6.1.4.1.9.9.719.1.15.56.1.7'; + my $oid_cucsEquipmentPsuDn = '.1.3.6.1.4.1.9.9.719.1.15.56.1.2'; + + my $result = $self->{snmp}->get_multiple_table(oids => [ + { oid => $oid_cucsEquipmentPsuPresence }, + { oid => $oid_cucsEquipmentPsuOperState }, + { oid => $oid_cucsEquipmentPsuDn }, + ] + ); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsEquipmentPsuPresence}})) { + # index + $key =~ /\.(\d+)$/; + my $psu_index = $1; + my $psu_dn = $result->{$oid_cucsEquipmentPsuDn}->{$oid_cucsEquipmentPsuDn . '.' . $psu_index}; + my $psu_operstate = defined($result->{$oid_cucsEquipmentPsuOperState}->{$oid_cucsEquipmentPsuOperState . '.' . $psu_index}) ? + $result->{$oid_cucsEquipmentPsuOperState}->{$oid_cucsEquipmentPsuOperState . '.' . $psu_index} : 0; # unknown + my $psu_presence = defined($result->{$oid_cucsEquipmentPsuPresence}->{$oid_cucsEquipmentPsuPresence . '.' . $psu_index}) ? + $result->{$oid_cucsEquipmentPsuPresence}->{$oid_cucsEquipmentPsuPresence . '.' . $psu_index} : 0; + + next if ($self->absent_problem(section => 'psu', instance => $psu_dn)); + next if ($self->check_exclude(section => 'psu', instance => $psu_dn)); + + if (${$presence{$psu_presence}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$presence{$psu_presence}}[1], + short_msg => sprintf("power supply '%s' presence is: '%s'", + $psu_dn, ${$presence{$psu_presence}}[0]) + ); + next; + } + + $self->{components}->{psu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("power supply '%s' state is '%s' [presence: %s].", + $psu_dn, ${$operability{$psu_operstate}}[0], + ${$presence{$psu_presence}}[0] + )); + if (${$operability{$psu_operstate}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$operability{$psu_operstate}}[1], + short_msg => sprintf("power supply '%s' state is '%s'.", + $psu_dn, ${$operability{$psu_operstate}}[0] + ) + ); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/hardware/server/cisco/ucs/mode/equipment.pm b/centreon-plugins/hardware/server/cisco/ucs/mode/equipment.pm index a943f5eef..0f3d2ef18 100644 --- a/centreon-plugins/hardware/server/cisco/ucs/mode/equipment.pm +++ b/centreon-plugins/hardware/server/cisco/ucs/mode/equipment.pm @@ -40,6 +40,8 @@ use base qw(centreon::plugins::mode); use strict; use warnings; use hardware::server::cisco::ucs::mode::components::fan; +use hardware::server::cisco::ucs::mode::components::psu; +use hardware::server::cisco::ucs::mode::components::iocard; sub new { my ($class, %options) = @_; @@ -50,39 +52,34 @@ sub new { $options{options}->add_options(arguments => { "exclude:s" => { name => 'exclude' }, + "absent-problem:s" => { name => 'absent' }, "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 global { my ($self, %options) = @_; hardware::server::cisco::ucs::mode::components::fan::check($self); - - 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); - $total_components += $self->{components}->{$comp}->{total}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . ' ' . $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, - $self->{product_name}, $self->{serial}, $self->{romversion}) - ); + hardware::server::cisco::ucs::mode::components::psu::check($self); + hardware::server::cisco::ucs::mode::components::iocard::check($self); } sub component { @@ -90,12 +87,14 @@ sub component { if ($self->{option_results}->{component} eq 'fan') { hardware::server::cisco::ucs::mode::components::fan::check($self); + } elsif ($self->{option_results}->{component} eq 'psu') { + hardware::server::cisco::ucs::mode::components::psu::check($self); + } elsif ($self->{option_results}->{component} eq 'iocard') { + hardware::server::cisco::ucs::mode::components::iocard::check($self); } else { $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); $self->{output}->option_exit(); } - - } sub run { @@ -114,9 +113,9 @@ sub run { 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); - $total_components += $self->{components}->{$comp}->{total}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . ' ' . $self->{components}->{$comp}->{name}; + 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 = ', '; } @@ -126,20 +125,45 @@ sub run { $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, $section) = @_; + my ($self, %options) = @_; - if (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)$section(\s|,|$)/) { - $self->{output}->output_add(long_msg => sprintf("Skipping $section section.")); + 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; } +sub absent_problem { + my ($self, %options) = @_; + + if (defined($self->{option_results}->{absent}) && + $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf("Component '%s' instance '%s' is not present", + $options{section}, $options{instance})); + return 1; + } + + return 0; +} + 1; __END__ @@ -157,7 +181,18 @@ Can be: 'fan'. =item B<--exclude> -Exclude some parts (comma seperated list) (Example: --exclude=psu,fan). +Exclude some parts (comma seperated list) (Example: --exclude=fan) +Can also exclude specific instance: --exclude=fan#/sys/chassis-7/fan-module-1-7/fan-1# + +=item B<--absent-problem> + +Return an error if an entity is not 'present' (default is skipping) (comma seperated list) +Can be specific or global: --exclude=fan#/sys/chassis-7/fan-module-1-7/fan-1# + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). =back