From f72a1fdb33e27b6d41ea12caecae24c1f596294f Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 23 Jul 2021 14:04:53 +0200 Subject: [PATCH] enh(qnap/snmp): add qts os support (#2984) --- .../storage/qnap/snmp/mode/components/disk.pm | 67 ++++++++++- .../storage/qnap/snmp/mode/components/fan.pm | 22 +++- .../storage/qnap/snmp/mode/components/psu.pm | 38 +++++- .../storage/qnap/snmp/mode/components/raid.pm | 44 ++++++- .../qnap/snmp/mode/components/temperature.pm | 18 ++- .../storage/qnap/snmp/mode/hardware.pm | 11 +- .../storage/qnap/snmp/mode/memory.pm | 17 ++- .../storage/qnap/snmp/mode/upgrade.pm | 111 ++++++++++++++++++ .../storage/qnap/snmp/mode/volumes.pm | 11 ++ centreon-plugins/storage/qnap/snmp/plugin.pm | 1 + 10 files changed, 329 insertions(+), 11 deletions(-) create mode 100644 centreon-plugins/storage/qnap/snmp/mode/upgrade.pm diff --git a/centreon-plugins/storage/qnap/snmp/mode/components/disk.pm b/centreon-plugins/storage/qnap/snmp/mode/components/disk.pm index 391602142..a432f58d2 100644 --- a/centreon-plugins/storage/qnap/snmp/mode/components/disk.pm +++ b/centreon-plugins/storage/qnap/snmp/mode/components/disk.pm @@ -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); diff --git a/centreon-plugins/storage/qnap/snmp/mode/components/fan.pm b/centreon-plugins/storage/qnap/snmp/mode/components/fan.pm index 32d9f0063..36236155f 100644 --- a/centreon-plugins/storage/qnap/snmp/mode/components/fan.pm +++ b/centreon-plugins/storage/qnap/snmp/mode/components/fan.pm @@ -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); diff --git a/centreon-plugins/storage/qnap/snmp/mode/components/psu.pm b/centreon-plugins/storage/qnap/snmp/mode/components/psu.pm index 381ab5094..80a12130b 100644 --- a/centreon-plugins/storage/qnap/snmp/mode/components/psu.pm +++ b/centreon-plugins/storage/qnap/snmp/mode/components/psu.pm @@ -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); diff --git a/centreon-plugins/storage/qnap/snmp/mode/components/raid.pm b/centreon-plugins/storage/qnap/snmp/mode/components/raid.pm index fda5922db..a96aaa1a3 100644 --- a/centreon-plugins/storage/qnap/snmp/mode/components/raid.pm +++ b/centreon-plugins/storage/qnap/snmp/mode/components/raid.pm @@ -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); } } diff --git a/centreon-plugins/storage/qnap/snmp/mode/components/temperature.pm b/centreon-plugins/storage/qnap/snmp/mode/components/temperature.pm index fd87592cd..5467fa451 100644 --- a/centreon-plugins/storage/qnap/snmp/mode/components/temperature.pm +++ b/centreon-plugins/storage/qnap/snmp/mode/components/temperature.pm @@ -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); diff --git a/centreon-plugins/storage/qnap/snmp/mode/hardware.pm b/centreon-plugins/storage/qnap/snmp/mode/hardware.pm index 73c331dc6..e06868f29 100644 --- a/centreon-plugins/storage/qnap/snmp/mode/hardware.pm +++ b/centreon-plugins/storage/qnap/snmp/mode/hardware.pm @@ -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 { diff --git a/centreon-plugins/storage/qnap/snmp/mode/memory.pm b/centreon-plugins/storage/qnap/snmp/mode/memory.pm index a47e6bed6..d4cd49981 100644 --- a/centreon-plugins/storage/qnap/snmp/mode/memory.pm +++ b/centreon-plugins/storage/qnap/snmp/mode/memory.pm @@ -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-*> diff --git a/centreon-plugins/storage/qnap/snmp/mode/upgrade.pm b/centreon-plugins/storage/qnap/snmp/mode/upgrade.pm new file mode 100644 index 000000000..c925dc938 --- /dev/null +++ b/centreon-plugins/storage/qnap/snmp/mode/upgrade.pm @@ -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 diff --git a/centreon-plugins/storage/qnap/snmp/mode/volumes.pm b/centreon-plugins/storage/qnap/snmp/mode/volumes.pm index 9b70e9bc3..67a4bf0c9 100644 --- a/centreon-plugins/storage/qnap/snmp/mode/volumes.pm +++ b/centreon-plugins/storage/qnap/snmp/mode/volumes.pm @@ -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)); diff --git a/centreon-plugins/storage/qnap/snmp/plugin.pm b/centreon-plugins/storage/qnap/snmp/plugin.pm index c2447d083..91d1f3732 100644 --- a/centreon-plugins/storage/qnap/snmp/plugin.pm +++ b/centreon-plugins/storage/qnap/snmp/plugin.pm @@ -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' };