enh(qnap/snmp): add qts os support (#2984)

This commit is contained in:
qgarnier 2021-07-23 14:04:53 +02:00 committed by GitHub
parent e00c47b961
commit 02d55a8019
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 329 additions and 11 deletions

View File

@ -44,6 +44,11 @@ my $mapping = {
status => { oid => '.1.3.6.1.4.1.24681.1.2.11.1.4', map => $map_status_disk }, # HdStatus
smartinfo => { oid => '.1.3.6.1.4.1.24681.1.2.11.1.7' } # HdSmartInfo
},
qts => {
description => { oid => '.1.3.6.1.4.1.55062.1.10.2.1.2' }, # diskID
status => { oid => '.1.3.6.1.4.1.55062.1.10.2.1.7' }, # diskStatus
temperature => { oid => '.1.3.6.1.4.1.55062.1.10.2.1.8' } # diskTemperature
},
ex => {
description => { oid => '.1.3.6.1.4.1.24681.1.4.1.1.1.1.5.2.1.2' }, # diskID
status => { oid => '.1.3.6.1.4.1.24681.1.4.1.1.1.1.5.2.1.5', map => $map_smartinfo }, # diskSmartInfo
@ -134,6 +139,64 @@ sub check_disk_legacy {
}
}
sub check_disk_qts {
my ($self, %options) = @_;
my $snmp_result = $self->{snmp}->get_table(
oid => '.1.3.6.1.4.1.55062.1.10.2', # diskTable
start => $mapping->{qts}->{description}->{oid},
end => $mapping->{qts}->{temperature}->{oid}
);
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %$snmp_result)) {
next if ($oid !~ /^$mapping->{qts}->{description}->{oid}\.(\d+)$/);
my $instance = $1;
$self->{disk_checked} = 1;
my $result = $self->{snmp}->map_instance(mapping => $mapping->{qts}, results => $snmp_result, instance => $instance);
next if ($self->check_filter(section => 'disk', instance => $instance));
$self->{components}->{disk}->{total}++;
$self->{output}->output_add(
long_msg => sprintf(
"disk '%s' status is %s [instance: %s, temperature: %s]",
$result->{description},
$result->{status},
$instance,
$result->{temperature}
)
);
my $exit = $self->get_severity(section => 'disk', instance => $instance, value => $result->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf(
"Disk '%s' status is %s.", $result->{description}, $result->{status}
)
);
}
next if ($result->{temperature} !~ /([0-9]+)/);
my $disk_temp = $1;
my ($exit2, $warn, $crit) = $self->get_severity_numeric(section => 'disk', instance => $instance, value => $disk_temp);
if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit2,
short_msg => sprintf(
"Disk '%s' temperature is %s degree centigrade", $result->{description}, $disk_temp
)
);
}
$self->{output}->perfdata_add(
nlabel => 'hardware.disk.temperature.celsius',
unit => 'C',
instances => $instance,
value => $disk_temp
);
}
}
sub check_disk_ex {
my ($self, %options) = @_;
@ -264,7 +327,9 @@ sub check {
$self->{components}->{disk} = { name => 'disks', total => 0, skip => 0 };
return if ($self->check_filter(section => 'disk'));
if ($self->{is_es} == 1) {
if ($self->{is_qts} == 1) {
check_disk_qts($self);
} elsif ($self->{is_es} == 1) {
check_disk_es($self);
} else {
check_disk_ex($self);

View File

@ -32,6 +32,10 @@ my $mapping = {
description => { oid => '.1.3.6.1.4.1.24681.1.2.15.1.2' }, # sysFanDescr
speed => { oid => '.1.3.6.1.4.1.24681.1.2.15.1.3' } # sysFanSpeed
},
qts => {
description => { oid => '.1.3.6.1.4.1.55062.1.12.9.1.2' }, # sysFanDescr
speed => { oid => '.1.3.6.1.4.1.55062.1.12.9.1.3' } # sysFanSpeed
},
ex => {
description => { oid => '.1.3.6.1.4.1.24681.1.4.1.1.1.1.2.2.1.2' }, # systemFanID
status => { oid => '.1.3.6.1.4.1.24681.1.4.1.1.1.1.2.2.1.4', map => $map_status }, # systemFanStatus
@ -68,7 +72,7 @@ sub check_fan_result {
)
);
if ($result->{speed} =~ /([0-9]+)\s*rpm/i) {
if ($result->{speed} =~ /([0-9]+)/i) {
my $fan_speed_value = $1;
my ($exit, $warn, $crit) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $fan_speed_value);
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
@ -100,6 +104,18 @@ sub check_fan_es {
check_fan_result($self, type => 'es', snmp_result => $snmp_result);
}
sub check_fan_qts {
my ($self, %options) = @_;
return if (defined($self->{fan_checked}));
my $snmp_result = $self->{snmp}->get_table(
oid => '.1.3.6.1.4.1.55062.1.12.9', # systemFanTable
start => $mapping->{qts}->{description}->{oid}
);
check_fan_result($self, type => 'qts', snmp_result => $snmp_result);
}
sub check_fan_legacy {
my ($self, %options) = @_;
@ -129,7 +145,9 @@ sub check {
$self->{components}->{fan} = {name => 'fans', total => 0, skip => 0};
return if ($self->check_filter(section => 'fan'));
if ($self->{is_es} == 1) {
if ($self->{is_qts} == 1) {
check_fan_qts($self);
} elsif ($self->{is_es} == 1) {
check_fan_es($self);
} else {
check_fan_ex($self);

View File

@ -111,6 +111,40 @@ sub check_psu_result {
}
}
sub check_psu_qts {
my ($self, %options) = @_;
my $oid_sysPowerStatus = '.1.3.6.1.4.1.55062.1.12.19.0';
my $snmp_result = $self->{snmp}->get_leef(
oids => [$oid_sysPowerStatus]
);
return if (!defined($snmp_result->{$oid_sysPowerStatus}));
my $instance = 1;
my $status = $map_status->{ $snmp_result->{$oid_sysPowerStatus} };
return if ($self->check_filter(section => 'psu', instance => $instance));
$self->{components}->{psu}->{total}++;
$self->{output}->output_add(
long_msg => sprintf(
"system power supply status is '%s' [instance: %s]",
$status, $instance
)
);
my $exit = $self->get_severity(section => 'psu', value => $status);
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf(
"Sytem power supply status is '%s'", $status
)
);
}
}
sub check_psu_es {
my ($self, %options) = @_;
@ -138,7 +172,9 @@ sub check {
$self->{components}->{psu} = { name => 'psu', total => 0, skip => 0 };
return if ($self->check_filter(section => 'psu'));
if ($self->{is_es} == 1) {
if ($self->{is_qts} == 1) {
check_psu_qts($self);
} elsif ($self->{is_es} == 1) {
check_psu_es($self);
} else {
check_psu_ex($self);

View File

@ -25,11 +25,49 @@ use warnings;
sub load {}
sub check_raid_qts {
my ($self) = @_;
my $mapping = {
name => { oid => '.1.3.6.1.4.1.55062.1.10.5.1.3' }, # raidName
status => { oid => '.1.3.6.1.4.1.55062.1.10.5.1.4' } # raidStatus
};
my $snmp_result = $self->{snmp}->get_table(
oid => '.1.3.6.1.4.1.55062.1.10.5', # raidTable
start => $mapping->{name}->{oid},
end => $mapping->{status}->{oid}
);
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %$snmp_result)) {
next if ($oid !~ /^$mapping->{status}->{oid}\.(\d+)$/);
my $instance = $1;
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance);
next if ($self->check_filter(section => 'raid', instance => $instance));
$self->{components}->{raid}->{total}++;
$self->{output}->output_add(
long_msg => sprintf(
"raid '%s' status is %s [instance: %s]",
$result->{name}, $result->{status}, $instance
)
);
my $exit = $self->get_severity(section => 'raid', value => $result->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf(
"Raid '%s' status is %s.", $result->{name}, $result->{status}
)
);
}
}
}
sub check_raid_ex {
my ($self) = @_;
my $snmp_result = $self->{snmp}->get_table(
oid => '.1.3.6.1.4.1.24681.1.4.1.1.1.2.1.2.1.5', # raidStatus
oid => '.1.3.6.1.4.1.24681.1.4.1.1.1.2.1.2.1.5' # raidStatus
);
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %$snmp_result)) {
$oid =~ /\.(\d+)$/;
@ -64,7 +102,9 @@ sub check {
$self->{components}->{raid} = {name => 'raids', total => 0, skip => 0};
return if ($self->check_filter(section => 'raid'));
if ($self->{is_es} == 0) {
if ($self->{is_qts} == 1) {
check_raid_qts($self);
} elsif ($self->{is_es} == 0) {
check_raid_ex($self);
}
}

View File

@ -28,6 +28,10 @@ my $mapping = {
cpu_temp => { oid => '.1.3.6.1.4.1.24681.1.2.5' }, # cpu-Temperature
system_temp => { oid => '.1.3.6.1.4.1.24681.1.2.6' } # systemTemperature
},
qts => {
cpu_temp => { oid => '.1.3.6.1.4.1.55062.1.12.10' }, # cpuTemperature
system_temp => { oid => '.1.3.6.1.4.1.55062.1.12.11' } # systemTemperature
},
ex => {
cpu_temp => { oid => '.1.3.6.1.4.1.24681.1.3.5' }, # cpu-TemperatureEX
system_temp => { oid => '.1.3.6.1.4.1.24681.1.3.6' } # systemTemperatureEX
@ -98,6 +102,16 @@ sub check_temp_result {
}
}
sub check_temp_qts {
my ($self, %options) = @_;
my $snmp_result = $self->{snmp}->get_leef(
oids => [ map($_->{oid} . '.0', values(%{$mapping->{qts}})) ]
);
my $result = $self->{snmp}->map_instance(mapping => $mapping->{qts}, results => $snmp_result, instance => 0);
check_temp_result($self, result => $result);
}
sub check_temp_es {
my ($self, %options) = @_;
@ -130,7 +144,9 @@ sub check {
$self->{components}->{temperature} = { name => 'temperatures', total => 0, skip => 0 };
return if ($self->check_filter(section => 'temperature'));
if ($self->{is_es} == 1) {
if ($self->{is_qts} == 1) {
check_temp_qts($self);
} elsif ($self->{is_es} == 1) {
check_temp_es($self);
} else {
check_temp($self);

View File

@ -85,11 +85,18 @@ sub snmp_execute {
$self->{snmp} = $options{snmp};
$self->{is_es} = 0;
my $oid_es_uptime = '.1.3.6.1.4.1.24681.2.2.4.0';
my $snmp_result = $self->{snmp}->get_leef(oids => [$oid_es_uptime]); # es-SystemUptime
$self->{is_qts} = 0;
my $oid_es_uptime = '.1.3.6.1.4.1.24681.2.2.4.0'; # es-SystemUptime
my $oid_qts_model = '.1.3.6.1.4.1.55062.1.12.3.0'; # systemModel
my $snmp_result = $self->{snmp}->get_leef(
oids => [$oid_es_uptime, $oid_qts_model]
);
if (defined($snmp_result->{$oid_es_uptime})) {
$self->{is_es} = 1;
}
if (defined($snmp_result->{$oid_qts_model})) {
$self->{is_qts} = 1;
}
}
sub new {

View File

@ -119,6 +119,10 @@ my $mapping = {
es => {
ram_total => { oid => '.1.3.6.1.4.1.24681.2.2.2' }, # es-SystemTotalMem
ram_free => { oid => '.1.3.6.1.4.1.24681.2.2.3' } # es-SystemFreeMem
},
qts => {
ram_total => { oid => '.1.3.6.1.4.1.55062.1.12.13' }, # systemTotalMem
ram_free => { oid => '.1.3.6.1.4.1.55062.1.12.15' } # systemAvailableMem
}
};
@ -150,10 +154,19 @@ sub manage_selection {
my ($self, %options) = @_;
my $snmp_result = $options{snmp}->get_leef(
oids => [ map($_->{oid} . '.0', values(%{$mapping->{legacy}}), values(%{$mapping->{ex}}), values(%{$mapping->{es}})) ],
oids => [
map(
$_->{oid} . '.0',
values(%{$mapping->{legacy}}),
values(%{$mapping->{ex}}),
values(%{$mapping->{es}}),
values(%{$mapping->{qts}})
)
],
nothing_quit => 1
);
if (!defined($self->{option_results}->{force_counters_legacy})) {
$self->check_memory(snmp => $options{snmp}, type => 'qts', snmp_result => $snmp_result);
$self->check_memory(snmp => $options{snmp}, type => 'ex', snmp_result => $snmp_result);
$self->check_memory(snmp => $options{snmp}, type => 'es', snmp_result => $snmp_result, convert => 1);
}
@ -172,7 +185,7 @@ Check memory.
=item B<--force-counters-legacy>
Force to use legacy counters. Should be used when EX/ES counters are buggy.
Force to use legacy counters. Should be used when EX/ES/QTS counters are buggy.
=item B<--warning-*> B<--critical-*>

View File

@ -0,0 +1,111 @@
#
# Copyright 2021 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package storage::qnap::snmp::mode::upgrade;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0 }
];
$self->{maps_counters}->{global} = [
{ label => 'status', type => 2, warning_default => '%{upgrade} eq "available"', set => {
key_values => [
{ name => 'model' }, { name => 'version' }, { name => 'upgrade' }
],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
sub custom_status_output {
my ($self, %options) = @_;
return sprintf(
"upgrade is %s [model: %s] [version: %s]",
$self->{result_values}->{upgrade},
$self->{result_values}->{model},
$self->{result_values}->{version}
);
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
});
return $self;
}
my $mapping = {
model => { oid => '.1.3.6.1.4.1.55062.1.12.3' }, # systemModel
version => { oid => '.1.3.6.1.4.1.55062.1.12.6' }, # firmwareVersion
upgrade => { oid => '.1.3.6.1.4.1.55062.1.12.7' } # firmwareUpgradeAvailable
};
sub manage_selection {
my ($self, %options) = @_;
my $snmp_result = $options{snmp}->get_leef(
oids => [ map($_->{oid} . '.0', values(%$mapping)) ],
nothing_quit => 1
);
$snmp_result->{$mapping->{version}->{oid} . '.0'} =~ s/\r*\n*$//;
$self->{global} = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => 0);
$self->{global}->{upgrade} = $self->{global}->{upgrade} ? 'available' : 'unavailable';
}
1;
__END__
=head1 MODE
Check upgrade status (only works with QTS OS).
=over 8
=item B<--warning-status>
Set warning threshold for status (Default : '%{upgrade} eq "available"').
Can used special variables like: %{model}, %{version}, %{upgrade}
=item B<--critical-status>
Set critical threshold for status.
Can used special variables like: %{model}, %{version}, %{upgrade}
=back
=cut

View File

@ -171,6 +171,12 @@ my $mapping = {
free => { oid => '.1.3.6.1.4.1.24681.1.4.1.1.1.2.3.2.1.4' }, # volumeFreeSize
status => { oid => '.1.3.6.1.4.1.24681.1.4.1.1.1.2.3.2.1.5' }, # volumeStatus
name => { oid => '.1.3.6.1.4.1.24681.1.4.1.1.1.2.3.2.1.8' } # volumeName
},
qts => {
total => { oid => '.1.3.6.1.4.1.55062.1.10.9.1.3' }, # volumeCapacity
free => { oid => '.1.3.6.1.4.1.55062.1.10.9.1.4' }, # volumeFreeSize
status => { oid => '.1.3.6.1.4.1.55062.1.10.9.1.5' }, # volumeStatus
name => { oid => '.1.3.6.1.4.1.55062.1.10.9.1.8' } # volumeName
}
};
@ -223,6 +229,11 @@ sub manage_selection {
$self->{volumes} = {};
my $snmp_result = $options{snmp}->get_table(
oid => '.1.3.6.1.4.1.55062.1.10.9' # volumeTable
);
return if ($self->check_volumes(snmp => $options{snmp}, type => 'qts', snmp_result => $snmp_result));
$snmp_result = $options{snmp}->get_table(
oid => '.1.3.6.1.4.1.24681.1.4.1.1.1.2.3.2' # volumeTable
);
return if ($self->check_volumes(snmp => $options{snmp}, type => 'ex', snmp_result => $snmp_result));

View File

@ -42,6 +42,7 @@ sub new {
'processcount' => 'snmp_standard::mode::processcount',
'storage' => 'snmp_standard::mode::storage',
'time' => 'snmp_standard::mode::ntp',
'upgrade' => 'storage::qnap::snmp::mode::upgrade',
'uptime' => 'snmp_standard::mode::uptime',
'volumes' => 'storage::qnap::snmp::mode::volumes'
};