diff --git a/centreon-plugins/storage/netapp.zip b/centreon-plugins/storage/netapp.zip new file mode 100644 index 000000000..69f47d000 Binary files /dev/null and b/centreon-plugins/storage/netapp.zip differ diff --git a/centreon-plugins/storage/netapp/mode/aggregatestate.pm b/centreon-plugins/storage/netapp/mode/aggregatestate.pm deleted file mode 100644 index dc81d8cee..000000000 --- a/centreon-plugins/storage/netapp/mode/aggregatestate.pm +++ /dev/null @@ -1,204 +0,0 @@ -################################################################################ -# 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::netapp::mode::aggregatestate; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my $oid_aggrName = '.1.3.6.1.4.1.789.1.5.11.1.2'; -my $oid_aggrState = '.1.3.6.1.4.1.789.1.5.11.1.5'; -my $oid_aggrStatus = '.1.3.6.1.4.1.789.1.5.11.1.6'; - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - - $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warn" => { name => 'warn' }, - "crit" => { name => 'crit' }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "state:s" => { name => 'state', default => 'online' }, - "status:s" => { name => 'status', default => 'ok|mirrored' }, - }); - $self->{aggregate_id_selected} = []; - $self->{status} = 'OK'; - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (defined($self->{option_results}->{warn})) { - $self->{status} = 'WARNING'; - } - if (defined($self->{option_results}->{crit})) { - $self->{status} = 'CRITICAL'; - } -} - -sub manage_selection { - my ($self, %options) = @_; - - $self->{result_names} = $self->{snmp}->get_table(oid => $oid_aggrName, nothing_quit => 1); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{result_names}})) { - next if ($oid !~ /\.([0-9]+)$/); - my $instance = $1; - - # Get all without a name - if (!defined($self->{option_results}->{name})) { - push @{$self->{aggregate_id_selected}}, $instance; - next; - } - - if (!defined($self->{option_results}->{use_regexp}) && $self->{result_names}->{$oid} eq $self->{option_results}->{name}) { - push @{$self->{aggregate_id_selected}}, $instance; - } - if (defined($self->{option_results}->{use_regexp}) && $self->{result_names}->{$oid} =~ /$self->{option_results}->{name}/) { - push @{$self->{aggregate_id_selected}}, $instance; - } - } - - if (scalar(@{$self->{aggregate_id_selected}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No aggregate found for name '" . $self->{option_results}->{name} . "'."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - $self->{snmp}->load(oids => [$oid_aggrState, $oid_aggrStatus], instances => $self->{aggregate_id_selected}); - my $result = $self->{snmp}->get_leef(); - - if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All aggregates status are ok.'); - } - - my $failed_state = 0; - my $failed_status = 0; - foreach my $instance (sort @{$self->{aggregate_id_selected}}) { - my $name = $self->{result_names}->{$oid_aggrName . '.' . $instance}; - my $aggr_state = $result->{$oid_aggrState . '.' . $instance}; - my $aggr_status = $result->{$oid_aggrStatus . '.' . $instance}; - - $self->{output}->output_add(long_msg => sprintf("Aggregate '%s' state: '%s', status: '%s'", $name, $aggr_state, $aggr_status)); - - my $status; - my $status_state = 'OK'; - my $status_status = 'OK'; - if (defined($self->{option_results}->{state}) && $aggr_state !~ /$self->{option_results}->{state}/) { - $status_state = $self->{status}; - $failed_state++; - } - if (defined($self->{option_results}->{status}) && $aggr_status !~ /$self->{option_results}->{status}/) { - $status_status = $self->{status}; - $failed_status++; - } - - $status = $self->{output}->get_most_critical(status => [ $status_status, $status_state ]); - - # Can be 'ok' if we don't set a threshold option '--warn', '--crit' - if (!$self->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $status, - short_msg => sprintf("Aggregat '%s' state: '%s', status: '%s'", $name, $aggr_state, $aggr_status)); - } elsif (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => $status, - short_msg => sprintf("Aggregat '%s' status is ok", $name)); - } - } - - $self->{output}->perfdata_add(label => 'failed_state', - value => $failed_state, - min => 0); - - $self->{output}->perfdata_add(label => 'failed_status', - value => $failed_status, - min => 0); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check state and status from aggregates. - -=over 8 - -=item B<--warn> - -Return Warning. - -=item B<--crit> - -Return Critical. - -=item B<--name> - -Set the aggregate name. - -=item B<--regexp> - -Allows to use regexp to filter volume name (with option --name). - -=item B<--state> - -State to check (Default: 'online'). - -=item B<--status> - -Status to check (Default: 'ok|mirrored'). - -=back - -=cut - diff --git a/centreon-plugins/storage/netapp/mode/fan.pm b/centreon-plugins/storage/netapp/mode/fan.pm deleted file mode 100644 index 8d54723d8..000000000 --- a/centreon-plugins/storage/netapp/mode/fan.pm +++ /dev/null @@ -1,95 +0,0 @@ -################################################################################ -# 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::netapp::mode::fan; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - - $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $oid_envFailedFanCount = '.1.3.6.1.4.1.789.1.2.4.2.0'; - my $oid_envFailedFanMessage = '.1.3.6.1.4.1.789.1.2.4.3.0'; - my $result = $self->{snmp}->get_leef(oids => [$oid_envFailedFanCount, $oid_envFailedFanMessage], nothing_quit => 1); - - $self->{output}->output_add(severity => 'OK', - short_msg => 'Fans are ok.'); - if ($result->{$oid_envFailedFanCount} != 0) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("'%d' fans are failed [message: %s].", - $result->{$oid_envFailedFanCount}, $result->{$oid_envFailedFanMessage})); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check if fans are failed (not operating within the recommended RPM range). - -=over 8 - -=back - -=cut - \ No newline at end of file diff --git a/centreon-plugins/storage/netapp/mode/filesys.pm b/centreon-plugins/storage/netapp/mode/filesys.pm deleted file mode 100644 index 956d09d08..000000000 --- a/centreon-plugins/storage/netapp/mode/filesys.pm +++ /dev/null @@ -1,270 +0,0 @@ -################################################################################ -# 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::netapp::mode::filesys; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my $oid_dfFileSys = '.1.3.6.1.4.1.789.1.5.4.1.2'; -my $oid_dfType = '.1.3.6.1.4.1.789.1.5.4.1.23'; -my $oid_dfKBytesTotal = '.1.3.6.1.4.1.789.1.5.4.1.3'; -my $oid_dfKBytesUsed = '.1.3.6.1.4.1.789.1.5.4.1.4'; -my $oid_dfKBytesAvail = '.1.3.6.1.4.1.789.1.5.4.1.5'; -my $oid_df64TotalKBytes = '.1.3.6.1.4.1.789.1.5.4.1.29'; -my $oid_df64UsedKBytes = '.1.3.6.1.4.1.789.1.5.4.1.30'; -my $oid_df64AvailKBytes = '.1.3.6.1.4.1.789.1.5.4.1.31'; -my $oid_dfDedupeSavedPercent = '.1.3.6.1.4.1.789.1.5.4.1.40'; -my $oid_dfCompressSavedPercent = '.1.3.6.1.4.1.789.1.5.4.1.38'; - -my %map_types = ( - 1 => 'traditionalVolume', - 2 => 'flexibleVolume', - 3 => 'aggregate', - 4 => 'stripedAggregate', - 5 => 'stripedVolume' -); - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - - $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "type:s" => { name => 'type' }, - }); - $self->{filesys_id_selected} = []; - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } -} - -sub manage_selection { - my ($self, %options) = @_; - - $self->{result_names} = $self->{snmp}->get_table(oid => $oid_dfFileSys, nothing_quit => 1); - $self->{result_types} = $self->{snmp}->get_table(oid => $oid_dfType, nothing_quit => 1); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{result_names}})) { - next if ($oid !~ /\.([0-9]+)$/); - my $instance = $1; - my $type = $map_types{$self->{result_types}->{$oid_dfType . '.' . $instance}}; - - # Get all without a name - if (!defined($self->{option_results}->{name})) { - push @{$self->{filesys_id_selected}}, $instance; - next; - } - - if (!defined($self->{option_results}->{use_regexp}) && $self->{result_names}->{$oid} eq $self->{option_results}->{name}) { - next if (defined($self->{option_results}->{type}) && $type !~ /$self->{option_results}->{type}/i); - push @{$self->{filesys_id_selected}}, $instance; - } - if (defined($self->{option_results}->{use_regexp}) && $self->{result_names}->{$oid} =~ /$self->{option_results}->{name}/) { - next if (defined($self->{option_results}->{type}) && $type !~ /$self->{option_results}->{type}/i); - push @{$self->{filesys_id_selected}}, $instance; - } - } - - if (scalar(@{$self->{filesys_id_selected}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No filesys found for name '" . $self->{option_results}->{name} . "' (can be the 'type' filter also)."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - if (!$self->{snmp}->is_snmpv1()) { - $self->{snmp}->load(oids => [$oid_df64TotalKBytes, $oid_df64UsedKBytes, $oid_df64AvailKBytes], instances => $self->{filesys_id_selected}); - } - $self->{snmp}->load(oids => [$oid_dfKBytesTotal, $oid_dfKBytesUsed, $oid_dfKBytesAvail, $oid_dfDedupeSavedPercent, $oid_dfCompressSavedPercent], instances => $self->{filesys_id_selected}); - my $result = $self->{snmp}->get_leef(); - - if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All filesys are ok.'); - } - - foreach my $instance (sort @{$self->{filesys_id_selected}}) { - my $name = $self->{result_names}->{$oid_dfFileSys . '.' . $instance}; - my $type = $self->{result_types}->{$oid_dfType . '.' . $instance}; - my ($total_size, $total_used, $total_free) = ($result->{$oid_dfKBytesTotal . '.' . $instance} * 1024, $result->{$oid_dfKBytesUsed . '.' . $instance} * 1024, $result->{$oid_dfKBytesAvail . '.' . $instance} * 1024); - if (defined($result->{$oid_df64TotalKBytes . '.' . $instance}) && $result->{$oid_df64TotalKBytes . '.' . $instance} != 0) { - ($total_size, $total_used, $total_free) = ($result->{$oid_df64TotalKBytes . '.' . $instance} * 1024, $result->{$oid_df64UsedKBytes . '.' . $instance} * 1024, $result->{$oid_df64AvailKBytes . '.' . $instance} * 1024); - } - - if ($total_size == 0) { - $self->{output}->output_add(long_msg => sprintf("Skipping filesys '%s' (total size is 0)", $name)); - if (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("Skipping filesys '%s' (total size is 0)", $name)); - } - next; - } - - ####### - # Calc - ####### - my $prct_used = $total_used * 100 / $total_size; - my $prct_free = 100 - $prct_used; - my ($exit, $threshold_value); - - $threshold_value = $total_used; - $threshold_value = $total_free if (defined($self->{option_results}->{free})); - if ($self->{option_results}->{units} eq '%') { - $threshold_value = $prct_used; - $threshold_value = $prct_free if (defined($self->{option_results}->{free})); - } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $total_size); - my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $total_used); - my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => ($total_size - $total_used)); - - $self->{output}->output_add(long_msg => sprintf("Filesys '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%) [type: %s]", $name, - $total_size_value . " " . $total_size_unit, - $total_used_value . " " . $total_used_unit, $prct_used, - $total_free_value . " " . $total_free_unit, $prct_free, $map_types{$type})); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp}))) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Filesys '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $name, - $total_size_value . " " . $total_size_unit, - $total_used_value . " " . $total_used_unit, $prct_used, - $total_free_value . " " . $total_free_unit, $prct_free)); - } - - my $label = 'used'; - my $value_perf = $total_used; - if (defined($self->{option_results}->{free})) { - $label = 'free'; - $value_perf = $total_free; - } - my $extra_label = ''; - $extra_label = '_' . $name if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})); - my %total_options = (); - if ($self->{option_results}->{units} eq '%') { - $total_options{total} = $total_size; - $total_options{cast_int} = 1; - } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', %total_options), - min => 0, max => $total_size); - - if (defined($result->{$oid_dfDedupeSavedPercent . '.' . $instance})) { - $self->{output}->perfdata_add(label => 'dedupsaved' . $extra_label, unit => '%', - value => $result->{$oid_dfDedupeSavedPercent . '.' . $instance}, - min => 0, max => 100); - } - if (defined($result->{$oid_dfCompressSavedPercent . '.' . $instance})) { - $self->{output}->perfdata_add(label => 'compresssaved' . $extra_label, unit => '%', - value => $result->{$oid_dfCompressSavedPercent . '.' . $instance}, - min => 0, max => 100); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check filesystem usage (volumes and aggregates also). - -=over 8 - -=item B<--warning> - -Threshold warning. - -=item B<--critical> - -Threshold critical. - -=item B<--units> - -Units of thresholds (Default: '%') ('%', 'B'). - -=item B<--free> - -Thresholds are on free space left. - -=item B<--name> - -Set the filesystem name. - -=item B<--regexp> - -Allows to use regexp to filter filesystem name (with option --name). - -=item B<--type> - -Filter filesystem type (a regexp. Example: 'flexibleVolume|aggregate'). - -=back - -=cut - \ No newline at end of file diff --git a/centreon-plugins/storage/netapp/mode/nvram.pm b/centreon-plugins/storage/netapp/mode/nvram.pm deleted file mode 100644 index 7573371ca..000000000 --- a/centreon-plugins/storage/netapp/mode/nvram.pm +++ /dev/null @@ -1,99 +0,0 @@ -################################################################################ -# 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::netapp::mode::nvram; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my %states = ( - 1 => ['ok', 'OK'], - 2 => ['partially discharged', 'WARNING'], - 3 => ['fully discharged', 'CRITICAL'], - 4 => ['not present', 'CRITICAL'], - 5 => ['near end of life', 'WARNING'], - 6 => ['at end of life', 'CRITICAL'], - 7 => ['unknown', 'UNKNOWN'], -); - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - - $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $oid_nvramBatteryStatus = '.1.3.6.1.4.1.789.1.2.5.1.0'; - my $result = $self->{snmp}->get_leef(oids => [$oid_nvramBatteryStatus], nothing_quit => 1); - - $self->{output}->output_add(severity => ${$states{$result->{$oid_nvramBatteryStatus}}}[1], - short_msg => sprintf("NVRAM Batteries status is '%s'.", ${$states{$result->{$oid_nvramBatteryStatus}}}[0])); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check current status of the NVRAM batteries. - -=over 8 - -=back - -=cut - \ No newline at end of file diff --git a/centreon-plugins/storage/netapp/mode/partnerstatus.pm b/centreon-plugins/storage/netapp/mode/partnerstatus.pm deleted file mode 100644 index 5089b4ae1..000000000 --- a/centreon-plugins/storage/netapp/mode/partnerstatus.pm +++ /dev/null @@ -1,118 +0,0 @@ -################################################################################ -# 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::netapp::mode::partnerstatus; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my %states = ( - 1 => ['maybe down', 'WARNING'], - 2 => ['ok', 'OK'], - 3 => ['dead', 'CRITICAL'], -); -my %connect_state = ( - 1 => ['not present', 'CRITICAL'], - 2 => ['down', 'CRITICAL'], - 3 => ['partial failure', 'WARNING'], - 4 => ['up', 'OK'], -); - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - - $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $oid_cfPartnerStatus = '.1.3.6.1.4.1.789.1.2.3.4.0'; - my $oid_cfPartnerName = '.1.3.6.1.4.1.789.1.2.3.6.0'; - my $oid_cfInterconnectStatus = '.1.3.6.1.4.1.789.1.2.3.8.0'; - my $result = $self->{snmp}->get_leef(oids => [$oid_cfPartnerStatus, $oid_cfPartnerName, $oid_cfInterconnectStatus], nothing_quit => 1); - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("Partner '%s' status is '%s'", $result->{$oid_cfPartnerName}, - ${$states{$result->{$oid_cfPartnerStatus}}}[0])); - if (${$states{$result->{$oid_cfPartnerStatus}}}[1] ne 'OK') { - $self->{output}->output_add(severity => ${$states{$result->{$oid_cfPartnerStatus}}}[1], - short_msg => sprintf("Partner '%s' status is '%s'", $result->{$oid_cfPartnerName}, - ${$states{$result->{$oid_cfPartnerStatus}}}[0])); - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("Interconnect status is '%s'", - ${$connect_state{$result->{$oid_cfInterconnectStatus}}}[0])); - if (${$connect_state{$result->{$oid_cfInterconnectStatus}}}[1] ne 'OK') { - $self->{output}->output_add(severity => ${$connect_state{$result->{$oid_cfInterconnectStatus}}}[1], - short_msg => sprintf("Interconnect status is '%s'", - ${$connect_state{$result->{$oid_cfInterconnectStatus}}}[0])); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check status of clustered failover partner. - -=over 8 - -=back - -=cut - \ No newline at end of file diff --git a/centreon-plugins/storage/netapp/mode/psu.pm b/centreon-plugins/storage/netapp/mode/psu.pm deleted file mode 100644 index bfe81b54b..000000000 --- a/centreon-plugins/storage/netapp/mode/psu.pm +++ /dev/null @@ -1,95 +0,0 @@ -################################################################################ -# 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::netapp::mode::psu; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - - $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $oid_envFailedPowerSupplyCount = '.1.3.6.1.4.1.789.1.2.4.4.0'; - my $oid_envFailedPowerSupplyMessage = '.1.3.6.1.4.1.789.1.2.4.5.0'; - my $result = $self->{snmp}->get_leef(oids => [$oid_envFailedPowerSupplyCount, $oid_envFailedPowerSupplyMessage], nothing_quit => 1); - - $self->{output}->output_add(severity => 'OK', - short_msg => 'Power supplies are ok.'); - if ($result->{$oid_envFailedPowerSupplyCount} != 0) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("'%d' power supplies are failed [message: %s].", - $result->{$oid_envFailedPowerSupplyCount}, $result->{$oid_envFailedPowerSupplyMessage})); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check if power supplies are failed (in degraded mode). - -=over 8 - -=back - -=cut - \ No newline at end of file diff --git a/centreon-plugins/storage/netapp/snmp/mode/aggregatestate.pm b/centreon-plugins/storage/netapp/snmp/mode/aggregatestate.pm new file mode 100644 index 000000000..16ffeaa0c --- /dev/null +++ b/centreon-plugins/storage/netapp/snmp/mode/aggregatestate.pm @@ -0,0 +1,311 @@ +################################################################################ +# Copyright 2005-2014 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::netapp::snmp::mode::aggregatestate; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::values; + +my $thresholds = { + state => [ + ['online', 'OK'], + ['offline', 'CRITICAL'], + ], + status => [ + ['normal', 'OK'], + ['mirrored', 'OK'], + ['.*', 'CRITICAL'], + ], +}; +my $instance_mode; + +my $maps_counters = { + agg => { + '000_state' => { set => { + key_values => [ { name => 'aggrState' } ], + closure_custom_calc => \&custom_state_calc, + output_template => "State : '%s'", output_error_template => "State : '%s'", + output_use => 'aggrState', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&custom_state_threshold, + } + }, + '001_status' => { set => { + key_values => [ { name => 'aggrStatus' } ], + closure_custom_calc => \&custom_status_calc, + output_template => "Status : '%s'", output_error_template => "Status : '%s'", + output_use => 'aggrStatus', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&custom_status_threshold, + } + }, + }, +}; + +sub custom_state_threshold { + my ($self, %options) = @_; + + return $instance_mode->get_severity(section => 'state', value => $self->{result_values}->{aggrState}); +} + +sub custom_state_calc { + my ($self, %options) = @_; + + $self->{result_values}->{aggrState} = $options{new_datas}->{$self->{instance} . '_aggrState'}; + return 0; +} + +sub custom_status_threshold { + my ($self, %options) = @_; + + return $instance_mode->get_severity(section => 'status', value => $self->{result_values}->{aggrStatus}); +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{aggrStatus} = $options{new_datas}->{$self->{instance} . '_aggrStatus'}; + return 0; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); + + foreach my $key (('agg')) { + foreach (keys %{$maps_counters->{$key}}) { + my ($id, $name) = split /_/; + if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { + $options{options}->add_options(arguments => { + 'warning-' . $name . ':s' => { name => 'warning-' . $name }, + 'critical-' . $name . ':s' => { name => 'critical-' . $name }, + }); + } + $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, + label => $name); + $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); + } + } + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + foreach my $key (('agg')) { + foreach (keys %{$maps_counters->{$key}}) { + $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); + } + } + + $instance_mode = $self; + + $self->{overload_th} = {}; + foreach my $val (@{$self->{option_results}->{threshold_overload}}) { + if ($val !~ /^(.*?),(.*?),(.*)$/) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); + $self->{output}->option_exit(); + } + my ($section, $status, $filter) = ($1, $2, $3); + if ($self->{output}->is_litteral_status(status => $status) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); + $self->{output}->option_exit(); + } + $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); + push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status}; + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->manage_selection(); + + my $multiple = 1; + if (scalar(keys %{$self->{agg}}) == 1) { + $multiple = 0; + } + + if ($multiple == 1) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'All aggregates status are ok'); + } + + foreach my $id (sort keys %{$self->{agg}}) { + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits = (); + foreach (sort keys %{$maps_counters->{agg}}) { + my $obj = $maps_counters->{agg}->{$_}->{obj}; + $obj->set(instance => $id); + + my ($value_check) = $obj->execute(values => $self->{agg}->{$id}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $obj->output_error(); + $long_msg_append = ', '; + next; + } + my $exit2 = $obj->threshold_check(); + push @exits, $exit2; + + my $output = $obj->output(); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + + if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + $maps_counters->{agg}->{$_}->{obj}->perfdata(extra_instance => $multiple); + } + + $self->{output}->output_add(long_msg => "Aggregate '$self->{agg}->{$id}->{aggrName}' $long_msg"); + my $exit = $self->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => "Aggregate '$self->{agg}->{$id}->{aggrName}' $short_msg" + ); + } + + if ($multiple == 0) { + $self->{output}->output_add(short_msg => "Aggregate '$self->{agg}->{$id}->{aggrName}' Usage $long_msg"); + } + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub get_severity { + my ($self, %options) = @_; + my $status = 'UNKNOWN'; # default + + if (defined($self->{overload_th}->{$options{section}})) { + foreach (@{$self->{overload_th}->{$options{section}}}) { + if ($options{value} =~ /$_->{filter}/i) { + $status = $_->{status}; + return $status; + } + } + } + foreach (@{$thresholds->{$options{section}}}) { + if ($options{value} =~ /$$_[0]/i) { + $status = $$_[1]; + return $status; + } + } + + return $status; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_aggrName = '.1.3.6.1.4.1.789.1.5.11.1.2'; + my $oid_aggrState = '.1.3.6.1.4.1.789.1.5.11.1.5'; + my $oid_aggrStatus = '.1.3.6.1.4.1.789.1.5.11.1.6'; + $self->{results} = $self->{snmp}->get_multiple_table(oids => [ + { oid => $oid_aggrName }, + { oid => $oid_aggrState }, + { oid => $oid_aggrStatus }, + ], + , nothing_quit => 1); + + $self->{agg} = {}; + foreach my $oid (keys %{$self->{results}->{$oid_aggrState}}) { + next if ($oid !~ /^$oid_aggrState\.(.*)$/); + my $instance = $1; + my $name = $self->{results}->{$oid_aggrName}->{$oid_aggrName . '.' . $instance}; + my $state = $self->{results}->{$oid_aggrState}->{$oid_aggrState . '.' . $instance}; + my $status = $self->{results}->{$oid_aggrStatus}->{$oid_aggrStatus . '.' . $instance}; + + if (!defined($state) || $state eq '') { + $self->{output}->output_add(long_msg => "Skipping '" . $name . "': state value not set."); + next; + } + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $name . "': no matching filter name."); + next; + } + + $self->{agg}->{$instance} = { aggrName => $name, aggrState => $state, aggrStatus => $status}; + } + + if (scalar(keys %{$self->{agg}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No aggregate found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check state and status from aggregates. + +=over 8 + +=item B<--filter-name> + +Filter by aggregate name. + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='state,CRITICAL,^(?!(online)$)' + +=back + +=cut diff --git a/centreon-plugins/storage/netapp/mode/components/communication.pm b/centreon-plugins/storage/netapp/snmp/mode/components/communication.pm similarity index 98% rename from centreon-plugins/storage/netapp/mode/components/communication.pm rename to centreon-plugins/storage/netapp/snmp/mode/components/communication.pm index 2e37c557c..70f88c4df 100644 --- a/centreon-plugins/storage/netapp/mode/components/communication.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/components/communication.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::components::communication; +package storage::netapp::snmp::mode::components::communication; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/storage/netapp/mode/components/electronics.pm b/centreon-plugins/storage/netapp/snmp/mode/components/electronics.pm similarity index 98% rename from centreon-plugins/storage/netapp/mode/components/electronics.pm rename to centreon-plugins/storage/netapp/snmp/mode/components/electronics.pm index 62cf702dc..4231d5967 100644 --- a/centreon-plugins/storage/netapp/mode/components/electronics.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/components/electronics.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::components::electronics; +package storage::netapp::snmp::mode::components::electronics; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/storage/netapp/mode/components/fan.pm b/centreon-plugins/storage/netapp/snmp/mode/components/fan.pm similarity index 98% rename from centreon-plugins/storage/netapp/mode/components/fan.pm rename to centreon-plugins/storage/netapp/snmp/mode/components/fan.pm index aee355834..b088b89ce 100644 --- a/centreon-plugins/storage/netapp/mode/components/fan.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/components/fan.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::components::fan; +package storage::netapp::snmp::mode::components::fan; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/storage/netapp/mode/components/psu.pm b/centreon-plugins/storage/netapp/snmp/mode/components/psu.pm similarity index 98% rename from centreon-plugins/storage/netapp/mode/components/psu.pm rename to centreon-plugins/storage/netapp/snmp/mode/components/psu.pm index 085327531..3fdae50c9 100644 --- a/centreon-plugins/storage/netapp/mode/components/psu.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/components/psu.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::components::psu; +package storage::netapp::snmp::mode::components::psu; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/storage/netapp/mode/components/raid.pm b/centreon-plugins/storage/netapp/snmp/mode/components/raid.pm similarity index 98% rename from centreon-plugins/storage/netapp/mode/components/raid.pm rename to centreon-plugins/storage/netapp/snmp/mode/components/raid.pm index b6cc56c3a..40c3f5a09 100644 --- a/centreon-plugins/storage/netapp/mode/components/raid.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/components/raid.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::components::raid; +package storage::netapp::snmp::mode::components::raid; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/storage/netapp/mode/components/temperature.pm b/centreon-plugins/storage/netapp/snmp/mode/components/temperature.pm similarity index 99% rename from centreon-plugins/storage/netapp/mode/components/temperature.pm rename to centreon-plugins/storage/netapp/snmp/mode/components/temperature.pm index 604a8a9e1..ee958d7a2 100644 --- a/centreon-plugins/storage/netapp/mode/components/temperature.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/components/temperature.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::components::temperature; +package storage::netapp::snmp::mode::components::temperature; use strict; use warnings; diff --git a/centreon-plugins/storage/netapp/mode/components/voltage.pm b/centreon-plugins/storage/netapp/snmp/mode/components/voltage.pm similarity index 99% rename from centreon-plugins/storage/netapp/mode/components/voltage.pm rename to centreon-plugins/storage/netapp/snmp/mode/components/voltage.pm index 662647c10..3f7a1920d 100644 --- a/centreon-plugins/storage/netapp/mode/components/voltage.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/components/voltage.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::components::voltage; +package storage::netapp::snmp::mode::components::voltage; use strict; use warnings; diff --git a/centreon-plugins/storage/netapp/mode/cpstatistics.pm b/centreon-plugins/storage/netapp/snmp/mode/cpstatistics.pm similarity index 99% rename from centreon-plugins/storage/netapp/mode/cpstatistics.pm rename to centreon-plugins/storage/netapp/snmp/mode/cpstatistics.pm index 3ba16a3de..283abee0e 100644 --- a/centreon-plugins/storage/netapp/mode/cpstatistics.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/cpstatistics.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::cpstatistics; +package storage::netapp::snmp::mode::cpstatistics; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/storage/netapp/mode/cpuload.pm b/centreon-plugins/storage/netapp/snmp/mode/cpuload.pm similarity index 98% rename from centreon-plugins/storage/netapp/mode/cpuload.pm rename to centreon-plugins/storage/netapp/snmp/mode/cpuload.pm index 7400de6e2..f947ea045 100644 --- a/centreon-plugins/storage/netapp/mode/cpuload.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/cpuload.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::cpuload; +package storage::netapp::snmp::mode::cpuload; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/storage/netapp/mode/diskfailed.pm b/centreon-plugins/storage/netapp/snmp/mode/diskfailed.pm similarity index 96% rename from centreon-plugins/storage/netapp/mode/diskfailed.pm rename to centreon-plugins/storage/netapp/snmp/mode/diskfailed.pm index 8ba9e3b74..a70489459 100644 --- a/centreon-plugins/storage/netapp/mode/diskfailed.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/diskfailed.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::diskfailed; +package storage::netapp::snmp::mode::diskfailed; use base qw(centreon::plugins::mode); @@ -90,6 +90,7 @@ __END__ =head1 MODE Check the current number of disk broken. +If you are in cluster mode, the following mode doesn't work. Ask to netapp to add it :) =over 8 diff --git a/centreon-plugins/storage/netapp/snmp/mode/fan.pm b/centreon-plugins/storage/netapp/snmp/mode/fan.pm new file mode 100644 index 000000000..ec836ca65 --- /dev/null +++ b/centreon-plugins/storage/netapp/snmp/mode/fan.pm @@ -0,0 +1,124 @@ +################################################################################ +# 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::netapp::snmp::mode::fan; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_envFailedFanCount = '.1.3.6.1.4.1.789.1.2.4.2'; + my $oid_envFailedFanMessage = '.1.3.6.1.4.1.789.1.2.4.3'; + my $oid_nodeName = '.1.3.6.1.4.1.789.1.25.2.1.1'; + my $oid_nodeEnvFailedFanCount = '.1.3.6.1.4.1.789.1.25.2.1.19'; + my $oid_nodeEnvFailedFanMessage = '.1.3.6.1.4.1.789.1.25.2.1.20'; + my $results = $self->{snmp}->get_multiple_table(oids => [ + { oid => $oid_envFailedFanCount }, + { oid => $oid_envFailedFanMessage }, + { oid => $oid_nodeName }, + { oid => $oid_nodeEnvFailedFanCount }, + { oid => $oid_nodeEnvFailedFanMessage } + ], nothing_quit => 1); + + if (defined($results->{$oid_envFailedFanCount}->{$oid_envFailedFanCount . '.0'})) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'Fans are ok.'); + if ($results->{$oid_envFailedFanCount}->{$oid_envFailedFanCount . '.0'} != 0) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf("'%d' fans are failed [message: %s].", + $results->{$oid_envFailedFanCount}->{$oid_envFailedFanCount . '.0'}, + $results->{$oid_envFailedFanMessage}->{$oid_envFailedFanMessage . '.0'})); + } + } else { + $self->{output}->output_add(severity => 'OK', + short_msg => 'Fans are ok on all nodes'); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$results->{$oid_nodeEnvFailedFanCount}})) { + $oid =~ /^$oid_nodeEnvFailedFanCount\.(.*)$/; + my $instance = $1; + my $name = $results->{$oid_nodeName}->{$oid_nodeName . '.' . $instance}; + my $count = $results->{$oid_nodeEnvFailedFanCount}->{$oid}; + my $message = $results->{$oid_nodeEnvFailedFanMessage}->{$oid_nodeEnvFailedFanMessage . '.' . $instance}; + $self->{output}->output_add(long_msg => sprintf("'%d' fans are failed on node '%s' [message: %s]", + $count, $name, defined($message) ? $message : '-')); + if ($count != 0) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf("'%d' fans are failed on node '%s' [message: %s]", + $count, $name, defined($message) ? $message : '-')); + } + } + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check if fans are failed (not operating within the recommended RPM range). + +=over 8 + +=back + +=cut + \ No newline at end of file diff --git a/centreon-plugins/storage/netapp/snmp/mode/filesys.pm b/centreon-plugins/storage/netapp/snmp/mode/filesys.pm new file mode 100644 index 000000000..f95757eef --- /dev/null +++ b/centreon-plugins/storage/netapp/snmp/mode/filesys.pm @@ -0,0 +1,359 @@ +################################################################################ +# Copyright 2005-2014 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::netapp::snmp::mode::filesys; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::values; + +my $maps_counters = { + '000_usage' => { set => { + key_values => [ { name => 'name' }, { name => 'used' }, { name => 'total' }, + { name => 'dfCompressSavedPercent' }, { name => 'dfDedupeSavedPercent' } ], + closure_custom_calc => \&custom_usage_calc, + closure_custom_output => \&custom_usage_output, + closure_custom_perfdata => \&custom_usage_perfdata, + closure_custom_threshold_check => \&custom_usage_threshold, + } + }, +}; + +my $instance_mode; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + return if ($self->{result_values}->{total} <= 0); + my $label = 'used'; + my $value_perf = $self->{result_values}->{used}; + if (defined($instance_mode->{option_results}->{free})) { + $label = 'free'; + $value_perf = $self->{result_values}->{free}; + } + my $extra_label = ''; + $extra_label = '_' . $self->{result_values}->{name} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); + if ($instance_mode->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + min => 0, max => $self->{result_values}->{total}); + if (defined($self->{result_values}->{dfCompressSavedPercent}) && $self->{result_values}->{dfCompressSavedPercent} ne '' + $self->{result_values}->{dfCompressSavedPercent} >= 0) { + $self->{output}->perfdata_add(label => 'compresssaved' . $extra_label, unit => '%', + value => $self->{result_values}->{dfCompressSavedPercent}, + min => 0, max => 100); + } + if (defined($self->{result_values}->{dfDedupeSavedPercent}) && $self->{result_values}->{dfDedupeSavedPercent} ne '' + $self->{result_values}->{dfDedupeSavedPercent} >= 0) { + $self->{output}->perfdata_add(label => 'dedupsaved' . $extra_label, unit => '%', + value => $self->{result_values}->{dfDedupeSavedPercent}, + min => 0, max => 100); + } +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + return 'ok' if ($self->{result_values}->{total} <= 0); + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my $msg; + if ($self->{result_values}->{total} == 0) { + $msg = 'skipping: total size is 0'; + } elsif ($self->{result_values}->{total} < 0) { + $msg = 'skipping: negative total value (maybe use snmp v2c)'; + } else { + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + } + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_name'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{dfCompressSavedPercent} = $options{new_datas}->{$self->{instance} . '_dfCompressSavedPercent'}; + $self->{result_values}->{dfDedupeSavedPercent} = $options{new_datas}->{$self->{instance} . '_dfDedupeSavedPercent'}; + + return 0 if ($options{new_datas}->{$self->{instance} . '_total'} == 0); + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + + return 0; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "filter-name:s" => { name => 'filter_name' }, + "filter-type:s" => { name => 'filter_type' }, + }); + + foreach (keys %{$maps_counters}) { + my ($id, $name) = split /_/; + if (!defined($maps_counters->{$_}->{threshold}) || $maps_counters->{$_}->{threshold} != 0) { + $options{options}->add_options(arguments => { + 'warning-' . $name . ':s' => { name => 'warning-' . $name }, + 'critical-' . $name . ':s' => { name => 'critical-' . $name }, + }); + } + $maps_counters->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, + label => $name); + $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); + } + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + foreach (keys %{$maps_counters}) { + $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); + } + + $instance_mode = $self; +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->manage_selection(); + + my $multiple = 1; + if (scalar(keys %{$self->{filesys_selected}}) == 1) { + $multiple = 0; + } + + if ($multiple == 1) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'All filesys usages are ok'); + } + + foreach my $id (sort keys %{$self->{filesys_selected}}) { + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits; + foreach (sort keys %{$maps_counters}) { + $maps_counters->{$_}->{obj}->set(instance => $id); + + my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{filesys_selected}->{$id}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); + $long_msg_append = ', '; + next; + } + my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); + push @exits, $exit2; + + my $output = $maps_counters->{$_}->{obj}->output(); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + + if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + $maps_counters->{$_}->{obj}->perfdata(extra_instance => $multiple); + } + + $self->{output}->output_add(long_msg => "Filesys '" . $self->{filesys_selected}->{$id}->{name} . "' $long_msg"); + my $exit = $self->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => "Filesys '" . $self->{filesys_selected}->{$id}->{name} . "' $short_msg" + ); + } + + if ($multiple == 0) { + $self->{output}->output_add(short_msg => "Filesys '" . $self->{filesys_selected}->{$id}->{name} . "' $long_msg"); + } + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +my %map_types = ( + 1 => 'traditionalVolume', + 2 => 'flexibleVolume', + 3 => 'aggregate', + 4 => 'stripedAggregate', + 5 => 'stripedVolume' +); +my $mapping = { + dfType => { oid => '.1.3.6.1.4.1.789.1.5.4.1.23', map => \%map_types }, +}; +my $mapping2 = { + dfKBytesTotal => { oid => '.1.3.6.1.4.1.789.1.5.4.1.3' }, + dfKBytesUsed => { oid => '.1.3.6.1.4.1.789.1.5.4.1.4' }, + df64TotalKBytes => { oid => '.1.3.6.1.4.1.789.1.5.4.1.29' }, + df64UsedKBytes => { oid => '.1.3.6.1.4.1.789.1.5.4.1.30' }, + dfCompressSavedPercent => { oid => '.1.3.6.1.4.1.789.1.5.4.1.38' }, + dfDedupeSavedPercent => { oid => '.1.3.6.1.4.1.789.1.5.4.1.40' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_dfFileSys = '.1.3.6.1.4.1.789.1.5.4.1.2'; + + my $results = $self->{snmp}->get_multiple_table(oids => [ + { oid => $oid_dfFileSys }, + { oid => $mapping->{dfType}->{oid} }, + ], nothing_quit => 1); + $self->{filesys_selected} = {}; + foreach my $oid (keys %{$results->{$oid_dfFileSys}}) { + $oid =~ /^$oid_dfFileSys\.(\d+)/; + my $instance = $1; + my $name = $results->{$oid_dfFileSys}->{$oid}; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $results->{$mapping->{dfType}->{oid}}, instance => $instance); + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $name . "': no matching filter name."); + next; + } + if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && + $result->{dfType} !~ /$self->{option_results}->{filter_type}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $result->{dfType} . "': no matching filter type."); + next; + } + + $self->{filesys_selected}->{$instance} = { name => $name }; + } + + if (scalar(keys %{$self->{filesys_selected}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No entry found."); + $self->{output}->option_exit(); + } + + my $instances = [keys %{$self->{filesys_selected}}]; + if (!$self->{snmp}->is_snmpv1()) { + $self->{snmp}->load(oids => [$mapping2->{df64TotalKBytes}->{oid}, $mapping2->{df64UsedKBytes}->{oid}], instances => $instances); + } + $self->{snmp}->load(oids => [$mapping2->{dfKBytesTotal}->{oid}, $mapping2->{dfKBytesUsed}->{oid}, + $mapping2->{dfDedupeSavedPercent}->{oid}, $mapping2->{dfCompressSavedPercent}->{oid}], instances => $instances); + my $result = $self->{snmp}->get_leef(); + foreach (@$instances) { + my $result = $self->{snmp}->map_instance(mapping => $mapping2, results => $result, instance => $_); + $self->{filesys_selected}->{$_}->{total} = $result->{dfKBytesTotal} * 1024; + $self->{filesys_selected}->{$_}->{used} = $result->{dfKBytesUsed} * 1024; + if (defined($result->{df64TotalKBytes}) && $result->{df64TotalKBytes} > 0) { + $self->{filesys_selected}->{$_}->{total} = $result->{df64TotalKBytes} * 1024; + $self->{filesys_selected}->{$_}->{used} = $result->{df64UsedKBytes} * 1024; + } + $self->{filesys_selected}->{$_}->{dfCompressSavedPercent} = $result->{dfCompressSavedPercent}; + $self->{filesys_selected}->{$_}->{dfDedupeSavedPercent} = $result->{dfDedupeSavedPercent}; + } +} + +1; + +__END__ + +=head1 MODE + +Check filesystem usage (volumes, snapshots and aggregates also). + +=over 8 + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=item B<--filter-name> + +Filter by filesystem name (can be a regexp). + +=item B<--filter-type> + +Filter filesystem type (can be a regexp. Example: 'flexibleVolume|aggregate'). + +=back + +=cut diff --git a/centreon-plugins/storage/netapp/mode/globalstatus.pm b/centreon-plugins/storage/netapp/snmp/mode/globalstatus.pm similarity index 98% rename from centreon-plugins/storage/netapp/mode/globalstatus.pm rename to centreon-plugins/storage/netapp/snmp/mode/globalstatus.pm index 7c3f54ab2..6866764a6 100644 --- a/centreon-plugins/storage/netapp/mode/globalstatus.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/globalstatus.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::globalstatus; +package storage::netapp::snmp::mode::globalstatus; use base qw(centreon::plugins::mode); @@ -228,6 +228,7 @@ __END__ =head1 MODE Check the overall status of the appliance and some metrics (total read bytes per seconds and total write bytes per seconds). +If you are in cluster mode, the following mode doesn't work. Ask to netapp to add it :) =over 8 diff --git a/centreon-plugins/storage/netapp/mode/listfilesys.pm b/centreon-plugins/storage/netapp/snmp/mode/listfilesys.pm similarity index 99% rename from centreon-plugins/storage/netapp/mode/listfilesys.pm rename to centreon-plugins/storage/netapp/snmp/mode/listfilesys.pm index aa110378d..56734d2d1 100644 --- a/centreon-plugins/storage/netapp/mode/listfilesys.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/listfilesys.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::listfilesys; +package storage::netapp::snmp::mode::listfilesys; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/storage/netapp/mode/ndmpsessions.pm b/centreon-plugins/storage/netapp/snmp/mode/ndmpsessions.pm similarity index 98% rename from centreon-plugins/storage/netapp/mode/ndmpsessions.pm rename to centreon-plugins/storage/netapp/snmp/mode/ndmpsessions.pm index 43675b740..14046abb4 100644 --- a/centreon-plugins/storage/netapp/mode/ndmpsessions.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/ndmpsessions.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::ndmpsessions; +package storage::netapp::snmp::mode::ndmpsessions; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/storage/netapp/snmp/mode/nvram.pm b/centreon-plugins/storage/netapp/snmp/mode/nvram.pm new file mode 100644 index 000000000..c94dfb416 --- /dev/null +++ b/centreon-plugins/storage/netapp/snmp/mode/nvram.pm @@ -0,0 +1,192 @@ +################################################################################ +# 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::netapp::snmp::mode::nvram; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %mapping_nvram_state = ( + 1 => 'ok', + 2 => 'partiallyDischarged', + 3 => 'fullyDischarged', + 4 => 'notPresent', + 5 => 'nearEndOfLife', + 6 => 'atEndOfLife', + 7 => 'unknown', + 8 => 'overCharged', + 9 => 'fullyCharged', +); + +my $thresholds = { + nvram => [ + ['ok', 'OK'], + ['partiallyDischarged', 'WARNING'], + ['fullyDischarged', 'CRITICAL'], + ['notPresent', 'CRITICAL'], + ['nearEndOfLife', 'WARNING'], + ['atEndOfLife', 'CRITICAL'], + ['unknown', 'UNKNOWN'], + ['overCharged', 'OK'], + ['fullyCharged', 'OK'], + ], +}; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{overload_th} = {}; + foreach my $val (@{$self->{option_results}->{threshold_overload}}) { + if ($val !~ /^(.*?),(.*?),(.*)$/) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); + $self->{output}->option_exit(); + } + my ($section, $status, $filter) = ($1, $2, $3); + if ($self->{output}->is_litteral_status(status => $status) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); + $self->{output}->option_exit(); + } + $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); + push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status}; + } +} + +my $mapping = { + nvramBatteryStatus => { oid => '.1.3.6.1.4.1.789.1.2.5.1', map => \%mapping_nvram_state }, +}; +my $mapping2 = { + nodeNvramBatteryStatus => { oid => '.1.3.6.1.4.1.789.1.25.2.1.17', map => \%mapping_nvram_state }, +}; + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_nodeName = '.1.3.6.1.4.1.789.1.25.2.1.1'; + my $results = $self->{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{nvramBatteryStatus}->{oid} }, + { oid => $oid_nodeName }, + { oid => $mapping2->{nodeNvramBatteryStatus}->{oid} }, + ], nothing_quit => 1); + + if (defined($results->{$mapping->{nvramBatteryStatus}->{oid}}->{$mapping->{nvramBatteryStatus}->{oid} . '.0'})) { + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $results->{$mapping->{nvramBatteryStatus}->{oid}}, instance => '0'); + my $exit = $self->get_severity(section => 'nvram', value => $result->{nvramBatteryStatus}); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("NVRAM Batteries status is '%s'", $result->{nvramBatteryStatus})); + } else { + $self->{output}->output_add(severity => 'OK', + short_msg => 'NVRAM Batteries status are ok on all nodes'); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$results->{$mapping2->{nodeNvramBatteryStatus}->{oid}}})) { + $oid =~ /^$mapping2->{nodeNvramBatteryStatus}->{oid}\.(.*)$/; + my $instance = $1; + my $name = $results->{$oid_nodeName}->{$oid_nodeName . '.' . $instance}; + my $result = $self->{snmp}->map_instance(mapping => $mapping2, results => $results->{$mapping2->{nodeNvramBatteryStatus}->{oid}}, instance => $instance); + + my $exit = $self->get_severity(section => 'nvram', value => $result->{nodeNvramBatteryStatus}); + $self->{output}->output_add(long_msg => sprintf("NVRAM Batteries status is '%s' on node '%s'", + $result->{nodeNvramBatteryStatus}, $name)); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("NVRAM Batteries status is '%s' on node '%s'", + $result->{nodeNvramBatteryStatus}, $name)); + } + } + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub get_severity { + my ($self, %options) = @_; + my $status = 'UNKNOWN'; # default + + if (defined($self->{overload_th}->{$options{section}})) { + foreach (@{$self->{overload_th}->{$options{section}}}) { + if ($options{value} =~ /$_->{filter}/i) { + $status = $_->{status}; + return $status; + } + } + } + foreach (@{$thresholds->{$options{section}}}) { + if ($options{value} =~ /$$_[0]/i) { + $status = $$_[1]; + return $status; + } + } + + return $status; +} + +1; + +__END__ + +=head1 MODE + +Check current status of the NVRAM batteries. + +=over 8 + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='nvram,CRITICAL,^(?!(ok)$)' + +=back + +=cut + \ No newline at end of file diff --git a/centreon-plugins/storage/netapp/snmp/mode/partnerstatus.pm b/centreon-plugins/storage/netapp/snmp/mode/partnerstatus.pm new file mode 100644 index 000000000..916c785e8 --- /dev/null +++ b/centreon-plugins/storage/netapp/snmp/mode/partnerstatus.pm @@ -0,0 +1,216 @@ +################################################################################ +# 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::netapp::snmp::mode::partnerstatus; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %mapping_partner_status = ( + 1 => 'maybeDown', + 2 => 'ok', + 3 => 'dead', +); +my %mapping_interconnect_status = ( + 1 => 'notPresent', + 2 => 'down', + 3 => 'partialFailure', + 4 => 'up', +); +my $thresholds = { + partner => [ + ['maybeDown', 'WARNING'], + ['ok', 'OK'], + ['dead', 'CRITICAL'], + ], + interconnect => [ + ['notPresent', 'CRITICAL'], + ['down', 'CRITICAL'], + ['partialFailure', 'WARNING'], + ['up', 'OK'], + ], +}; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{overload_th} = {}; + foreach my $val (@{$self->{option_results}->{threshold_overload}}) { + if ($val !~ /^(.*?),(.*?),(.*)$/) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); + $self->{output}->option_exit(); + } + my ($section, $status, $filter) = ($1, $2, $3); + if ($self->{output}->is_litteral_status(status => $status) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); + $self->{output}->option_exit(); + } + $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); + push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status}; + } +} + +my $mapping = { + cfPartnerStatus => { oid => '.1.3.6.1.4.1.789.1.2.3.4', map => \%mapping_partner_status }, +}; +my $mapping2 = { + cfInterconnectStatus => { oid => '.1.3.6.1.4.1.789.1.2.3.8', map => \%mapping_interconnect_status }, +}; +my $mapping3 = { + haPartnerStatus => { oid => '.1.3.6.1.4.1.789.1.21.2.1.6', map => \%mapping_partner_status }, +}; +my $mapping4 = { + haInterconnectStatus => { oid => '.1.3.6.1.4.1.789.1.21.2.1.10', map => \%mapping_interconnect_status }, +}; + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_cfPartnerName = '.1.3.6.1.4.1.789.1.2.3.6'; + my $oid_haNodeName = '.1.3.6.1.4.1.789.1.21.2.1.1'; + my $results = $self->{snmp}->get_multiple_table(oids => [ + { oid => $oid_cfPartnerName }, + { oid => $mapping->{cfPartnerStatus}->{oid} }, + { oid => $mapping2->{cfInterconnectStatus}->{oid} }, + { oid => $oid_haNodeName }, + { oid => $mapping3->{haPartnerStatus}->{oid} }, + { oid => $mapping4->{haInterconnectStatus}->{oid} }, + ], nothing_quit => 1); + + if (defined($results->{$mapping->{cfPartnerStatus}->{oid}}->{$mapping->{cfPartnerStatus}->{oid} . '.0'})) { + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $results->{$mapping->{cfPartnerStatus}->{oid}}, instance => '0'); + my $exit = $self->get_severity(section => 'partner', value => $result->{cfPartnerStatus}); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Partner '%s' status is '%s'", $results->{$oid_cfPartnerName}->{$oid_cfPartnerName . '.0'}, $result->{cfPartnerStatus})); + $result = $self->{snmp}->map_instance(mapping => $mapping2, results => $results->{$mapping2->{cfInterconnectStatus}->{oid}}, instance => '0'); + $exit = $self->get_severity(section => 'interconnect', value => $result->{cfInterconnectStatus}); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Interconnect status is '%s'", $result->{cfInterconnectStatus})); + } else { + $self->{output}->output_add(severity => 'OK', + short_msg => 'HA status are ok on all nodes'); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$results->{$mapping3->{haPartnerStatus}->{oid}}})) { + $oid =~ /^$mapping3->{haPartnerStatus}->{oid}\.(.*)$/; + my $instance = $1; + my $name = $results->{$oid_haNodeName}->{$oid_haNodeName . '.' . $instance}; + my $result = $self->{snmp}->map_instance(mapping => $mapping3, results => $results->{$mapping3->{haPartnerStatus}->{oid}}, instance => $instance); + + my $exit = $self->get_severity(section => 'partner', value => $result->{haPartnerStatus}); + $self->{output}->output_add(long_msg => sprintf("Partner status of node '%s' is '%s'", + $name, $result->{haPartnerStatus})); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Partner status of node '%s' is '%s'", + $name, $result->{haPartnerStatus})); + } + + $result = $self->{snmp}->map_instance(mapping => $mapping4, results => $results->{$mapping4->{haInterconnectStatus}->{oid}}, instance => $instance); + $exit = $self->get_severity(section => 'interconnect', value => $result->{haInterconnectStatus}); + $self->{output}->output_add(long_msg => sprintf("Interconnect status on node '%s' is '%s'", + $name, $result->{haInterconnectStatus})); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Interconnect status on node '%s' is '%s'", + $name, $result->{haInterconnectStatus})); + } + } + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub get_severity { + my ($self, %options) = @_; + my $status = 'UNKNOWN'; # default + + if (defined($self->{overload_th}->{$options{section}})) { + foreach (@{$self->{overload_th}->{$options{section}}}) { + if ($options{value} =~ /$_->{filter}/i) { + $status = $_->{status}; + return $status; + } + } + } + foreach (@{$thresholds->{$options{section}}}) { + if ($options{value} =~ /$$_[0]/i) { + $status = $$_[1]; + return $status; + } + } + + return $status; +} + + +1; + +__END__ + +=head1 MODE + +Check status of clustered failover partner. + +=over 8 + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='partner,CRITICAL,^(?!(ok)$)' + +=back + +=cut + \ No newline at end of file diff --git a/centreon-plugins/storage/netapp/snmp/mode/psu.pm b/centreon-plugins/storage/netapp/snmp/mode/psu.pm new file mode 100644 index 000000000..3a084384f --- /dev/null +++ b/centreon-plugins/storage/netapp/snmp/mode/psu.pm @@ -0,0 +1,124 @@ +################################################################################ +# 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::netapp::snmp::mode::psu; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_envFailedPowerSupplyCount = '.1.3.6.1.4.1.789.1.2.4.4'; + my $oid_envFailedPowerSupplyMessage = '.1.3.6.1.4.1.789.1.2.4.5'; + my $oid_nodeName = '.1.3.6.1.4.1.789.1.25.2.1.1'; + my $oid_nodeEnvFailedPowerSupplyCount = '.1.3.6.1.4.1.789.1.25.2.1.21'; + my $oid_nodeEnvFailedPowerSupplyMessage = '.1.3.6.1.4.1.789.1.25.2.1.22'; + my $results = $self->{snmp}->get_multiple_table(oids => [ + { oid => $oid_envFailedPowerSupplyCount }, + { oid => $oid_envFailedPowerSupplyMessage }, + { oid => $oid_nodeName }, + { oid => $oid_nodeEnvFailedPowerSupplyCount }, + { oid => $oid_nodeEnvFailedPowerSupplyMessage } + ], nothing_quit => 1); + + if (defined($results->{$oid_envFailedPowerSupplyCount}->{$oid_envFailedPowerSupplyCount . '.0'})) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'Power supplies are ok.'); + if ($results->{$oid_envFailedPowerSupplyCount}->{$oid_envFailedPowerSupplyCount . '.0'} != 0) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf("'%d' power supplies are failed [message: %s].", + $results->{$oid_envFailedPowerSupplyCount}->{$oid_envFailedPowerSupplyCount . '.0'}, + $results->{$oid_envFailedPowerSupplyMessage}->{$oid_envFailedPowerSupplyMessage . '.0'})); + } + } else { + $self->{output}->output_add(severity => 'OK', + short_msg => 'Power supplies are ok on all nodes'); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$results->{$oid_nodeEnvFailedPowerSupplyCount}})) { + $oid =~ /^$oid_nodeEnvFailedPowerSupplyCount\.(.*)$/; + my $instance = $1; + my $name = $results->{$oid_nodeName}->{$oid_nodeName . '.' . $instance}; + my $count = $results->{$oid_nodeEnvFailedPowerSupplyCount}->{$oid}; + my $message = $results->{$oid_nodeEnvFailedPowerSupplyMessage}->{$oid_nodeEnvFailedPowerSupplyMessage . '.' . $instance}; + $self->{output}->output_add(long_msg => sprintf("'%d' power supplies are failed on node '%s' [message: %s]", + $count, $name, defined($message) ? $message : '-')); + if ($count != 0) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf("'%d' power supplies are failed on node '%s' [message: %s]", + $count, $name, defined($message) ? $message : '-')); + } + } + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check if power supplies are failed (in degraded mode). + +=over 8 + +=back + +=cut + \ No newline at end of file diff --git a/centreon-plugins/storage/netapp/snmp/mode/qtreeusage.pm b/centreon-plugins/storage/netapp/snmp/mode/qtreeusage.pm new file mode 100644 index 000000000..866b36d9e --- /dev/null +++ b/centreon-plugins/storage/netapp/snmp/mode/qtreeusage.pm @@ -0,0 +1,331 @@ +################################################################################ +# Copyright 2005-2014 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::netapp::snmp::mode::qtreeusage; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::values; + +my $maps_counters = { + '000_usage' => { set => { + key_values => [ { name => 'name' }, { name => 'used' }, { name => 'total' } ], + closure_custom_calc => \&custom_usage_calc, + closure_custom_output => \&custom_usage_output, + closure_custom_perfdata => \&custom_usage_perfdata, + closure_custom_threshold_check => \&custom_usage_threshold, + } + }, +}; + +my $instance_mode; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $label = 'used'; + my $value_perf = $self->{result_values}->{used}; + if ($self->{result_values}->{total} > 0 && defined($instance_mode->{option_results}->{free})) { + $label = 'free'; + $value_perf = $self->{result_values}->{free}; + } + my $extra_label = ''; + $extra_label = '_' . $self->{result_values}->{name} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); + if ($self->{result_values}->{total} > 0 && $instance_mode->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + # cannot use '%' or free option with unlimited system + return 'ok' if ($self->{result_values}->{total} <= 0 && ($instance_mode->{option_results}->{units} eq '%' || $instance_mode->{option_results}->{free})); + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my $msg; + if ($self->{result_values}->{total} <= 0) { + $msg = sprintf("Used: %s (unlimited)", $total_used_value . " " . $total_used_unit); + } else { + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + } + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_name'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + + return 0 if ($self->{result_values}->{total} == 0); + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + + return 0; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "filter-vserver:s" => { name => 'filter_vserver' }, + "filter-volume:s" => { name => 'filter_volume' }, + "filter-qtree:s" => { name => 'filter_qtree' }, + }); + + foreach (keys %{$maps_counters}) { + my ($id, $name) = split /_/; + if (!defined($maps_counters->{$_}->{threshold}) || $maps_counters->{$_}->{threshold} != 0) { + $options{options}->add_options(arguments => { + 'warning-' . $name . ':s' => { name => 'warning-' . $name }, + 'critical-' . $name . ':s' => { name => 'critical-' . $name }, + }); + } + $maps_counters->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, + label => $name); + $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); + } + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + foreach (keys %{$maps_counters}) { + $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); + } + + $instance_mode = $self; +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->manage_selection(); + + my $multiple = 1; + if (scalar(keys %{$self->{qtree_selected}}) == 1) { + $multiple = 0; + } + + if ($multiple == 1) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'All qtree usages are ok'); + } + + foreach my $id (sort keys %{$self->{qtree_selected}}) { + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits; + foreach (sort keys %{$maps_counters}) { + $maps_counters->{$_}->{obj}->set(instance => $id); + + my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{qtree_selected}->{$id}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); + $long_msg_append = ', '; + next; + } + my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); + push @exits, $exit2; + + my $output = $maps_counters->{$_}->{obj}->output(); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + + if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + $maps_counters->{$_}->{obj}->perfdata(extra_instance => $multiple); + } + + $self->{output}->output_add(long_msg => "Qtree '" . $self->{qtree_selected}->{$id}->{name} . "' $long_msg"); + my $exit = $self->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => "Qtree '" . $self->{qtree_selected}->{$id}->{name} . "' $short_msg" + ); + } + + if ($multiple == 0) { + $self->{output}->output_add(short_msg => "Qtree '" . $self->{qtree_selected}->{$id}->{name} . "' $long_msg"); + } + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +my $mapping = { + qrV2Tree => { oid => '.1.3.6.1.4.1.789.1.4.6.1.14' }, + qrV264KBytesUsed => { oid => '.1.3.6.1.4.1.789.1.4.6.1.25' }, + qrV264KBytesLimit => { oid => '.1.3.6.1.4.1.789.1.4.6.1.26' }, + qrV2VolumeName => { oid => '.1.3.6.1.4.1.789.1.4.6.1.29' }, + qrV2Vserver => { oid => '.1.3.6.1.4.1.789.1.4.6.1.30' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + if ($self->{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } + my $results = $self->{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{qrV2Tree}->{oid} }, + { oid => $mapping->{qrV264KBytesUsed}->{oid} }, + { oid => $mapping->{qrV264KBytesLimit}->{oid} }, + { oid => $mapping->{qrV2VolumeName}->{oid} }, + { oid => $mapping->{qrV2Vserver}->{oid} }, + ], return_type => 1, nothing_quit => 1); + $self->{qtree_selected} = {}; + foreach my $oid (keys %{$results}) { + next if ($oid !~ /^$mapping->{qrV2Tree}->{oid}\.(.*)/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance); + + if (defined($self->{option_results}->{filter_vserver}) && $self->{option_results}->{filter_vserver} ne '' && + $result->{qrV2Vserver} !~ /$self->{option_results}->{filter_vserver}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $result->{qrV2Vserver} . "': no matching vserver name."); + next; + } + if (defined($self->{option_results}->{filter_volume}) && $self->{option_results}->{filter_volume} ne '' && + $result->{qrV2VolumeName} !~ /$self->{option_results}->{filter_volume}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $result->{qrV2VolumeName} . "': no matching volume name."); + next; + } + if (defined($self->{option_results}->{filter_qtree}) && $self->{option_results}->{filter_qtree} ne '' && + $result->{qrV2Tree} !~ /$self->{option_results}->{filter_qtree}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $result->{qrV2Tree} . "': no matching qtree name."); + next; + } + + my $name = ''; + $name = $result->{qrV2Vserver} . '/' if (defined($result->{qrV2Vserver}) && $result->{qrV2Vserver} ne ''); + $name .= $result->{qrV2VolumeName} . '/' . $result->{qrV2Tree}; + + $self->{qtree_selected}->{$instance} = { name => $name, used => $result->{qrV264KBytesUsed}, total => $result->{qrV264KBytesLimit} }; + } + + if (scalar(keys %{$self->{qtree_selected}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No entry found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check qtree quote usage. + +=over 8 + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=item B<--filter-vserver> + +Filter by vserver name (can be a regexp). + +=item B<--filter-volume> + +Filter by volume name (can be a regexp). + +=item B<--filter-qtree> + +Filter by qtree name (can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/storage/netapp/mode/sharecalls.pm b/centreon-plugins/storage/netapp/snmp/mode/sharecalls.pm similarity index 98% rename from centreon-plugins/storage/netapp/mode/sharecalls.pm rename to centreon-plugins/storage/netapp/snmp/mode/sharecalls.pm index 080c5d84a..fca99357a 100644 --- a/centreon-plugins/storage/netapp/mode/sharecalls.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/sharecalls.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::sharecalls; +package storage::netapp::snmp::mode::sharecalls; use base qw(centreon::plugins::mode); @@ -190,6 +190,7 @@ __END__ =head1 MODE Check cifs and nfs calls per seconds. +If you are in cluster mode, the following mode doesn't work. Ask to netapp to add it :) =over 8 diff --git a/centreon-plugins/storage/netapp/mode/shelf.pm b/centreon-plugins/storage/netapp/snmp/mode/shelf.pm similarity index 98% rename from centreon-plugins/storage/netapp/mode/shelf.pm rename to centreon-plugins/storage/netapp/snmp/mode/shelf.pm index a4fb82850..17fff99dc 100644 --- a/centreon-plugins/storage/netapp/mode/shelf.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/shelf.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::shelf; +package storage::netapp::snmp::mode::shelf; use base qw(centreon::plugins::mode); @@ -174,7 +174,7 @@ sub run { my @components = ('communication', 'psu', 'fan', 'temperature', 'voltage', 'electronics', 'raid'); foreach (@components) { if (/$self->{option_results}->{component}/) { - my $mod_name = "storage::netapp::mode::components::$_"; + my $mod_name = "storage::netapp::snmp::mode::components::$_"; centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, error_msg => "Cannot load module '$mod_name'."); my $func = $mod_name->can('load'); @@ -194,7 +194,7 @@ sub run { foreach (@components) { if (/$self->{option_results}->{component}/) { - my $mod_name = "storage::netapp::mode::components::$_"; + my $mod_name = "storage::netapp::snmp::mode::components::$_"; my $func = $mod_name->can('check'); $func->($self); } diff --git a/centreon-plugins/storage/netapp/mode/snapmirrorlag.pm b/centreon-plugins/storage/netapp/snmp/mode/snapmirrorlag.pm similarity index 99% rename from centreon-plugins/storage/netapp/mode/snapmirrorlag.pm rename to centreon-plugins/storage/netapp/snmp/mode/snapmirrorlag.pm index 555da32b1..681200829 100644 --- a/centreon-plugins/storage/netapp/mode/snapmirrorlag.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/snapmirrorlag.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::snapmirrorlag; +package storage::netapp::snmp::mode::snapmirrorlag; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/storage/netapp/mode/snapshotage.pm b/centreon-plugins/storage/netapp/snmp/mode/snapshotage.pm similarity index 99% rename from centreon-plugins/storage/netapp/mode/snapshotage.pm rename to centreon-plugins/storage/netapp/snmp/mode/snapshotage.pm index c64e105b0..98e293ece 100644 --- a/centreon-plugins/storage/netapp/mode/snapshotage.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/snapshotage.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::snapshotage; +package storage::netapp::snmp::mode::snapshotage; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/storage/netapp/mode/temperature.pm b/centreon-plugins/storage/netapp/snmp/mode/temperature.pm similarity index 56% rename from centreon-plugins/storage/netapp/mode/temperature.pm rename to centreon-plugins/storage/netapp/snmp/mode/temperature.pm index 2273d3354..3a8b35385 100644 --- a/centreon-plugins/storage/netapp/mode/temperature.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/temperature.pm @@ -33,13 +33,18 @@ # #################################################################################### -package storage::netapp::mode::temperature; +package storage::netapp::snmp::mode::temperature; use base qw(centreon::plugins::mode); use strict; use warnings; +my %mapping_temperature = ( + 1 => 'no', + 2 => 'yes' +); + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -63,14 +68,37 @@ sub run { # $options{snmp} = snmp object $self->{snmp} = $options{snmp}; - my $oid_envOverTemperature = '.1.3.6.1.4.1.789.1.2.4.1.0'; - my $result = $self->{snmp}->get_leef(oids => [$oid_envOverTemperature], nothing_quit => 1); + my $oid_envOverTemperature = '.1.3.6.1.4.1.789.1.2.4.1'; + my $oid_nodeName = '.1.3.6.1.4.1.789.1.25.2.1.1'; + my $oid_nodeEnvOverTemperature = '.1.3.6.1.4.1.789.1.25.2.1.18'; + my $results = $self->{snmp}->get_multiple_table(oids => [ + { oid => $oid_envOverTemperature }, + { oid => $oid_nodeName }, + { oid => $oid_nodeEnvOverTemperature }, + ], nothing_quit => 1); - $self->{output}->output_add(severity => 'OK', - short_msg => 'Hardware temperature is ok.'); - if ($result->{$oid_envOverTemperature} == 2) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => 'Hardware temperature is over temperature range.'); + if (defined($results->{$oid_envOverTemperature}->{$oid_envOverTemperature . '.0'})) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'Hardware temperature is ok.'); + if ($mapping_temperature{$results->{$oid_envOverTemperature}->{$oid_envOverTemperature . '.0'}} eq 'yes') { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => 'Hardware temperature is over temperature range.'); + } + } else { + $self->{output}->output_add(severity => 'OK', + short_msg => 'Hardware temperature are ok on all nodes'); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$results->{$oid_nodeEnvOverTemperature}})) { + $oid =~ /^$oid_nodeEnvOverTemperature\.(.*)$/; + my $instance = $1; + my $name = $results->{$oid_nodeName}->{$oid_nodeName . '.' . $instance}; + my $temp = $results->{$oid_nodeEnvOverTemperature}->{$oid}; + $self->{output}->output_add(long_msg => sprintf("hardware temperature on node '%s' is over range: '%s'", + $name, $mapping_temperature{$temp})); + if ($mapping_temperature{$temp} eq 'yes') { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf("Hardware temperature is over temperature range on node '%s'", $name)); + } + } } $self->{output}->display(); diff --git a/centreon-plugins/storage/netapp/mode/volumeoptions.pm b/centreon-plugins/storage/netapp/snmp/mode/volumeoptions.pm similarity index 99% rename from centreon-plugins/storage/netapp/mode/volumeoptions.pm rename to centreon-plugins/storage/netapp/snmp/mode/volumeoptions.pm index 037147a01..56df9424a 100644 --- a/centreon-plugins/storage/netapp/mode/volumeoptions.pm +++ b/centreon-plugins/storage/netapp/snmp/mode/volumeoptions.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::mode::volumeoptions; +package storage::netapp::snmp::mode::volumeoptions; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/storage/netapp/plugin.pm b/centreon-plugins/storage/netapp/snmp/plugin.pm similarity index 85% rename from centreon-plugins/storage/netapp/plugin.pm rename to centreon-plugins/storage/netapp/snmp/plugin.pm index 09015242b..f0c7cce38 100644 --- a/centreon-plugins/storage/netapp/plugin.pm +++ b/centreon-plugins/storage/netapp/snmp/plugin.pm @@ -33,7 +33,7 @@ # #################################################################################### -package storage::netapp::plugin; +package storage::netapp::snmp::plugin; use strict; use warnings; @@ -47,24 +47,25 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'cp-statistics' => 'storage::netapp::mode::cpstatistics', - 'cpuload' => 'storage::netapp::mode::cpuload', - 'diskfailed' => 'storage::netapp::mode::diskfailed', - 'fan' => 'storage::netapp::mode::fan', - 'filesys' => 'storage::netapp::mode::filesys', - 'global-status' => 'storage::netapp::mode::globalstatus', - 'list-filesys' => 'storage::netapp::mode::listfilesys', - 'ndmpsessions' => 'storage::netapp::mode::ndmpsessions', - 'nvram' => 'storage::netapp::mode::nvram', - 'partnerstatus' => 'storage::netapp::mode::partnerstatus', - 'psu' => 'storage::netapp::mode::psu', - 'share-calls' => 'storage::netapp::mode::sharecalls', - 'shelf' => 'storage::netapp::mode::shelf', - 'snapmirrorlag' => 'storage::netapp::mode::snapmirrorlag', - 'temperature' => 'storage::netapp::mode::temperature', - 'volumeoptions' => 'storage::netapp::mode::volumeoptions', - 'aggregatestate' => 'storage::netapp::mode::aggregatestate', - 'snapshotage' => 'storage::netapp::mode::snapshotage', + 'aggregatestate' => 'storage::netapp::snmp::mode::aggregatestate', + 'cp-statistics' => 'storage::netapp::snmp::mode::cpstatistics', + 'cpuload' => 'storage::netapp::snmp::mode::cpuload', + 'diskfailed' => 'storage::netapp::snmp::mode::diskfailed', + 'fan' => 'storage::netapp::snmp::mode::fan', + 'filesys' => 'storage::netapp::snmp::mode::filesys', + 'list-filesys' => 'storage::netapp::snmp::mode::listfilesys', + 'global-status' => 'storage::netapp::snmp::mode::globalstatus', + 'ndmpsessions' => 'storage::netapp::snmp::mode::ndmpsessions', + 'nvram' => 'storage::netapp::snmp::mode::nvram', + 'partnerstatus' => 'storage::netapp::snmp::mode::partnerstatus', + 'psu' => 'storage::netapp::snmp::mode::psu', + 'qtree-usage' => 'storage::netapp::snmp::mode::qtreeusage', + 'share-calls' => 'storage::netapp::snmp::mode::sharecalls', + 'shelf' => 'storage::netapp::snmp::mode::shelf', + 'snapmirrorlag' => 'storage::netapp::snmp::mode::snapmirrorlag', + 'snapshotage' => 'storage::netapp::snmp::mode::snapshotage', + 'temperature' => 'storage::netapp::snmp::mode::temperature', + 'volumeoptions' => 'storage::netapp::snmp::mode::volumeoptions', ); return $self;