+ Enhance Netapp plugin for c-mode and add a qtree-usage mode

This commit is contained in:
garnier-quentin 2015-06-25 13:31:18 +02:00
parent ed53a65b12
commit b09354e5e0
34 changed files with 1736 additions and 928 deletions

BIN
storage/netapp.zip Normal file

Binary file not shown.

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::components::communication;
package storage::netapp::snmp::mode::components::communication;
use base qw(centreon::plugins::mode);

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::components::electronics;
package storage::netapp::snmp::mode::components::electronics;
use base qw(centreon::plugins::mode);

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::components::fan;
package storage::netapp::snmp::mode::components::fan;
use base qw(centreon::plugins::mode);

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::components::psu;
package storage::netapp::snmp::mode::components::psu;
use base qw(centreon::plugins::mode);

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::components::raid;
package storage::netapp::snmp::mode::components::raid;
use base qw(centreon::plugins::mode);

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::components::temperature;
package storage::netapp::snmp::mode::components::temperature;
use strict;
use warnings;

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::components::voltage;
package storage::netapp::snmp::mode::components::voltage;
use strict;
use warnings;

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::cpstatistics;
package storage::netapp::snmp::mode::cpstatistics;
use base qw(centreon::plugins::mode);

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::cpuload;
package storage::netapp::snmp::mode::cpuload;
use base qw(centreon::plugins::mode);

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::listfilesys;
package storage::netapp::snmp::mode::listfilesys;
use base qw(centreon::plugins::mode);

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::ndmpsessions;
package storage::netapp::snmp::mode::ndmpsessions;
use base qw(centreon::plugins::mode);

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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

View File

@ -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);
}

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::snapmirrorlag;
package storage::netapp::snmp::mode::snapmirrorlag;
use base qw(centreon::plugins::mode);

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::snapshotage;
package storage::netapp::snmp::mode::snapshotage;
use base qw(centreon::plugins::mode);

View File

@ -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();

View File

@ -33,7 +33,7 @@
#
####################################################################################
package storage::netapp::mode::volumeoptions;
package storage::netapp::snmp::mode::volumeoptions;
use base qw(centreon::plugins::mode);

View File

@ -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;