+ update hardware mode for extreme plugin (refactoring)

This commit is contained in:
garnier-quentin 2016-01-07 16:06:10 +01:00
parent cb39b7f2f0
commit 8d9e3d4b63
5 changed files with 71 additions and 246 deletions

View File

@ -35,9 +35,9 @@ my $mapping = {
my $oid_extremeFanStatusEntry = '.1.3.6.1.4.1.1916.1.1.1.9.1'; my $oid_extremeFanStatusEntry = '.1.3.6.1.4.1.1916.1.1.1.9.1';
sub load { sub load {
my (%options) = @_; my ($self) = @_;
push @{$options{request}}, { oid => $oid_extremeFanStatusEntry, end => $mapping->{extremeFanOperational}->{oid} }; push @{$self->{request}}, { oid => $oid_extremeFanStatusEntry, end => $mapping->{extremeFanOperational}->{oid} };
} }
sub check { sub check {
@ -45,7 +45,7 @@ sub check {
$self->{output}->output_add(long_msg => "Checking fans"); $self->{output}->output_add(long_msg => "Checking fans");
$self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0};
return if ($self->check_exclude(section => 'fan')); return if ($self->check_filter(section => 'fan'));
my ($exit, $warn, $crit, $checked); my ($exit, $warn, $crit, $checked);
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_extremeFanStatusEntry}})) { foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_extremeFanStatusEntry}})) {
@ -53,7 +53,7 @@ sub check {
my $instance = $1; my $instance = $1;
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_extremeFanStatusEntry}, instance => $instance); my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_extremeFanStatusEntry}, instance => $instance);
next if ($self->check_exclude(section => 'fan', instance => $instance)); next if ($self->check_filter(section => 'fan', instance => $instance));
$self->{components}->{fan}->{total}++; $self->{components}->{fan}->{total}++;
$self->{output}->output_add(long_msg => sprintf("Fan '%s' status is '%s' [instance = %s, speed = %s]", $self->{output}->output_add(long_msg => sprintf("Fan '%s' status is '%s' [instance = %s, speed = %s]",

View File

@ -40,9 +40,9 @@ my $mapping = {
my $oid_extremePowerSupplyEntry = '.1.3.6.1.4.1.1916.1.1.1.27.1'; my $oid_extremePowerSupplyEntry = '.1.3.6.1.4.1.1916.1.1.1.27.1';
sub load { sub load {
my (%options) = @_; my ($self) = @_;
push @{$options{request}}, { oid => $oid_extremePowerSupplyEntry, start => $mapping->{extremePowerSupplyStatus}->{oid} }; push @{$self->{request}}, { oid => $oid_extremePowerSupplyEntry, start => $mapping->{extremePowerSupplyStatus}->{oid} };
} }
sub check_fan_speed { sub check_fan_speed {
@ -69,14 +69,14 @@ sub check {
$self->{output}->output_add(long_msg => "Checking power supplies"); $self->{output}->output_add(long_msg => "Checking power supplies");
$self->{components}->{psu} = {name => 'power supplies', total => 0, skip => 0}; $self->{components}->{psu} = {name => 'power supplies', total => 0, skip => 0};
return if ($self->check_exclude(section => 'psu')); return if ($self->check_filter(section => 'psu'));
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_extremePowerSupplyEntry}})) { foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_extremePowerSupplyEntry}})) {
next if ($oid !~ /^$mapping->{extremePowerSupplyStatus}->{oid}\.(.*)$/); next if ($oid !~ /^$mapping->{extremePowerSupplyStatus}->{oid}\.(.*)$/);
my $instance = $1; my $instance = $1;
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_extremePowerSupplyEntry}, instance => $instance); my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_extremePowerSupplyEntry}, instance => $instance);
next if ($self->check_exclude(section => 'psu', instance => $instance)); next if ($self->check_filter(section => 'psu', instance => $instance));
if ($result->{extremePowerSupplyStatus} =~ /notPresent/i) { if ($result->{extremePowerSupplyStatus} =~ /notPresent/i) {
$self->absent_problem(section => 'psu', instance => $instance); $self->absent_problem(section => 'psu', instance => $instance);
next; next;

View File

@ -48,9 +48,9 @@ my $mapping = {
my $oid_extremeSlotEntry = '.1.3.6.1.4.1.1916.1.1.2.2.1'; my $oid_extremeSlotEntry = '.1.3.6.1.4.1.1916.1.1.2.2.1';
sub load { sub load {
my (%options) = @_; my ($self) = @_;
push @{$options{request}}, { oid => $oid_extremeSlotEntry, start => $mapping->{extremeSlotName}->{oid}, end => $mapping->{extremeSlotModuleState}->{oid} }; push @{$self->{request}}, { oid => $oid_extremeSlotEntry, start => $mapping->{extremeSlotName}->{oid}, end => $mapping->{extremeSlotModuleState}->{oid} };
} }
sub check { sub check {
@ -58,14 +58,14 @@ sub check {
$self->{output}->output_add(long_msg => "Checking slots"); $self->{output}->output_add(long_msg => "Checking slots");
$self->{components}->{slot} = {name => 'slots', total => 0, skip => 0}; $self->{components}->{slot} = {name => 'slots', total => 0, skip => 0};
return if ($self->check_exclude(section => 'slot')); return if ($self->check_filter(section => 'slot'));
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_extremeSlotEntry}})) { foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_extremeSlotEntry}})) {
next if ($oid !~ /^$mapping->{extremeSlotModuleState}->{oid}\.(.*)$/); next if ($oid !~ /^$mapping->{extremeSlotModuleState}->{oid}\.(.*)$/);
my $instance = $1; my $instance = $1;
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_extremeSlotEntry}, instance => $instance); my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_extremeSlotEntry}, instance => $instance);
next if ($self->check_exclude(section => 'slot', instance => $instance)); next if ($self->check_filter(section => 'slot', instance => $instance));
if ($result->{extremeSlotModuleState} =~ /notPresent/i) { if ($result->{extremeSlotModuleState} =~ /notPresent/i) {
$self->absent_problem(section => 'slot', instance => $instance); $self->absent_problem(section => 'slot', instance => $instance);
next; next;

View File

@ -28,9 +28,9 @@ my $mapping = {
}; };
sub load { sub load {
my (%options) = @_; my ($self) = @_;
push @{$options{request}}, { oid => $mapping->{extremeCurrentTemperature}->{oid} }; push @{$self->{request}}, { oid => $mapping->{extremeCurrentTemperature}->{oid} };
} }
sub check { sub check {
@ -38,13 +38,13 @@ sub check {
$self->{output}->output_add(long_msg => "Checking temperatures"); $self->{output}->output_add(long_msg => "Checking temperatures");
$self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0};
return if ($self->check_exclude(section => 'temperature')); return if ($self->check_filter(section => 'temperature'));
return if (!defined($self->{results}->{$mapping->{extremeCurrentTemperature}->{oid}}->{$mapping->{extremeCurrentTemperature}->{oid} . '.0'})); return if (!defined($self->{results}->{$mapping->{extremeCurrentTemperature}->{oid}}->{$mapping->{extremeCurrentTemperature}->{oid} . '.0'}));
my $instance = 0; my $instance = 0;
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{extremeCurrentTemperature}->{oid}}, instance => $instance); my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{extremeCurrentTemperature}->{oid}}, instance => $instance);
next if ($self->check_exclude(section => 'temperature', instance => $instance)); next if ($self->check_filter(section => 'temperature', instance => $instance));
$self->{components}->{temperature}->{total}++; $self->{components}->{temperature}->{total}++;
$self->{output}->output_add(long_msg => sprintf("temperature is %dC [instance: %s].", $self->{output}->output_add(long_msg => sprintf("temperature is %dC [instance: %s].",

View File

@ -20,40 +20,60 @@
package network::extreme::snmp::mode::hardware; package network::extreme::snmp::mode::hardware;
use base qw(centreon::plugins::mode); use base qw(centreon::plugins::templates::hardware);
use strict; use strict;
use warnings; use warnings;
my $thresholds = { sub set_system {
psu => [ my ($self, %options) = @_;
['notPresent', 'OK'],
['presentOK', 'OK'], $self->{regexp_threshold_overload_check_section_option} = '^(fan|psu|slot)$';
['presentPowerOff', 'WARNING'], $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|fan|psu\.power|psu\.fan)$';
['presentNotOK', 'CRITICAL'],
], $self->{cb_hook2} = 'snmp_execute';
fan => [
['not operational', 'CRITICAL'], #Example for threshold:
['operational', 'OK'], $self->{thresholds} = {
], psu => [
slot => [ ['notPresent', 'OK'],
['notPresent', 'OK'], ['presentOK', 'OK'],
['testing', 'OK'], ['presentPowerOff', 'WARNING'],
['mismatch', 'WARNING'], ['presentNotOK', 'CRITICAL'],
['failed', 'CRITICAL'], ],
['operational', 'OK'], fan => [
['powerdown', 'WARNING'], ['not operational', 'CRITICAL'],
['unknown', 'UNKNOWN'], ['operational', 'OK'],
['present', 'OK'], ],
['poweron', 'OK'], slot => [
['post', 'UNKNOWN'], ['notPresent', 'OK'],
['downloading', 'WARNING'], ['testing', 'OK'],
['booting', 'WARNING'], ['mismatch', 'WARNING'],
['offline', 'WARNING'], ['failed', 'CRITICAL'],
['initializing', 'OK'], ['operational', 'OK'],
['invalid', 'CRITICAL'], ['powerdown', 'WARNING'],
], ['unknown', 'UNKNOWN'],
}; ['present', 'OK'],
['poweron', 'OK'],
['post', 'UNKNOWN'],
['downloading', 'WARNING'],
['booting', 'WARNING'],
['offline', 'WARNING'],
['initializing', 'OK'],
['invalid', 'CRITICAL'],
],
};
$self->{components_path} = 'network::extreme::snmp::mode::components';
$self->{components_module} = ['fan', 'psu', 'slot', 'temperature'];
}
sub snmp_execute {
my ($self, %options) = @_;
$self->{snmp} = $options{snmp};
$self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request});
}
sub new { sub new {
my ($class, %options) = @_; my ($class, %options) = @_;
@ -63,206 +83,11 @@ sub new {
$self->{version} = '1.0'; $self->{version} = '1.0';
$options{options}->add_options(arguments => $options{options}->add_options(arguments =>
{ {
"exclude:s" => { name => 'exclude' },
"absent-problem:s" => { name => 'absent' },
"component:s" => { name => 'component', default => '.*' },
"no-component:s" => { name => 'no_component' },
"threshold-overload:s@" => { name => 'threshold_overload' },
"warning:s@" => { name => 'warning' },
"critical:s@" => { name => 'critical' },
}); });
$self->{components} = {};
$self->{no_components} = undef;
return $self; return $self;
} }
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
if (defined($self->{option_results}->{no_component})) {
if ($self->{option_results}->{no_component} ne '') {
$self->{no_components} = $self->{option_results}->{no_component};
} else {
$self->{no_components} = 'critical';
}
}
$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};
}
$self->{numeric_threshold} = {};
foreach my $option (('warning', 'critical')) {
foreach my $val (@{$self->{option_results}->{$option}}) {
if ($val !~ /^(.*?),(.*?),(.*)$/) {
$self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'.");
$self->{output}->option_exit();
}
my ($section, $regexp, $value) = ($1, $2, $3);
if ($section !~ /^(temperature|fan|psu\.power|psu\.fan)$/) {
$self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: temperature, fan, psu.power, psu.fan).");
$self->{output}->option_exit();
}
my $position = 0;
if (defined($self->{numeric_threshold}->{$section})) {
$position = scalar(@{$self->{numeric_threshold}->{$section}});
}
if (($self->{perfdata}->threshold_validate(label => $option . '-' . $section . '-' . $position, value => $value)) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong $option threshold '" . $value . "'.");
$self->{output}->option_exit();
}
$self->{numeric_threshold}->{$section} = [] if (!defined($self->{numeric_threshold}->{$section}));
push @{$self->{numeric_threshold}->{$section}}, { label => $option . '-' . $section . '-' . $position, threshold => $option, regexp => $regexp };
}
}
}
sub run {
my ($self, %options) = @_;
# $options{snmp} = snmp object
$self->{snmp} = $options{snmp};
my $snmp_request = [];
my @components = ('fan', 'psu', 'slot', 'temperature');
foreach (@components) {
if (/$self->{option_results}->{component}/) {
my $mod_name = "network::extreme::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');
$func->(request => $snmp_request);
}
}
if (scalar(@{$snmp_request}) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'.");
$self->{output}->option_exit();
}
$self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request);
foreach (@components) {
if (/$self->{option_results}->{component}/) {
my $mod_name = "network::extreme::snmp::mode::components::$_";
my $func = $mod_name->can('check');
$func->($self);
}
}
my $total_components = 0;
my $display_by_component = '';
my $display_by_component_append = '';
foreach my $comp (sort(keys %{$self->{components}})) {
# Skipping short msg when no components
next if ($self->{components}->{$comp}->{total} == 0 && $self->{components}->{$comp}->{skip} == 0);
$total_components += $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip};
my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip};
$display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name};
$display_by_component_append = ', ';
}
$self->{output}->output_add(severity => 'OK',
short_msg => sprintf("All %s components are ok [%s].",
$total_components,
$display_by_component)
);
if (defined($self->{option_results}->{no_component}) && $total_components == 0) {
$self->{output}->output_add(severity => $self->{no_components},
short_msg => 'No components are checked.');
}
$self->{output}->display();
$self->{output}->exit();
}
sub check_exclude {
my ($self, %options) = @_;
if (defined($options{instance})) {
if (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)${options{section}}[^,]*#\Q$options{instance}\E#/) {
$self->{components}->{$options{section}}->{skip}++;
$self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance."));
return 1;
}
} elsif (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)$options{section}(\s|,|$)/) {
$self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section."));
return 1;
}
return 0;
}
sub absent_problem {
my ($self, %options) = @_;
if (defined($self->{option_results}->{absent}) &&
$self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) {
$self->{output}->output_add(severity => 'CRITICAL',
short_msg => sprintf("Component '%s' instance '%s' is not present",
$options{section}, $options{instance}));
}
$self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)"));
$self->{components}->{$options{section}}->{skip}++;
return 1;
}
sub get_severity_numeric {
my ($self, %options) = @_;
my $status = 'OK'; # default
my $thresholds = { warning => undef, critical => undef };
my $checked = 0;
if (defined($self->{numeric_threshold}->{$options{section}})) {
my $exits = [];
foreach (@{$self->{numeric_threshold}->{$options{section}}}) {
if ($options{instance} =~ /$_->{regexp}/) {
push @{$exits}, $self->{perfdata}->threshold_check(value => $options{value}, threshold => [ { label => $_->{label}, exit_litteral => $_->{threshold} } ]);
$thresholds->{$_->{threshold}} = $self->{perfdata}->get_perfdata_for_output(label => $_->{label});
$checked = 1;
}
}
$status = $self->{output}->get_most_critical(status => $exits) if (scalar(@{$exits}) > 0);
}
return ($status, $thresholds->{warning}, $thresholds->{critical}, $checked);
}
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; 1;
__END__ __END__
@ -278,15 +103,15 @@ Check Hardware (Fans, Power Supplies, Slot, Temperature).
Which component to check (Default: '.*'). Which component to check (Default: '.*').
Can be: 'fan', 'psu', 'slot', 'temperature'. Can be: 'fan', 'psu', 'slot', 'temperature'.
=item B<--exclude> =item B<--filter>
Exclude some parts (comma seperated list) (Example: --exclude=fan) Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu)
Can also exclude specific instance: --exclude=fan#101# Can also exclude specific instance: --filter=fan,101
=item B<--absent-problem> =item B<--absent-problem>
Return an error if an entity is not 'present' (default is skipping) (comma seperated list) Return an error if an entity is not 'present' (default is skipping) (comma seperated list)
Can be specific or global: --absent-problem=psu#1# Can be specific or global: --absent-problem=psu,1
=item B<--no-component> =item B<--no-component>
@ -295,7 +120,7 @@ If total (with skipped) is 0. (Default: 'critical' returns).
=item B<--threshold-overload> =item B<--threshold-overload>
Set to overload default threshold values (syntax: section,status,regexp) Set to overload default threshold values (syntax: section,[instance,]status,regexp)
It used before default thresholds (order stays). It used before default thresholds (order stays).
Example: --threshold-overload='psu,CRITICAL,^(?!(presentOK)$)' Example: --threshold-overload='psu,CRITICAL,^(?!(presentOK)$)'