From 582996cbcb6ddd7a2d8721377e8d5c0cc0b987c5 Mon Sep 17 00:00:00 2001 From: UrBnW <40244829+UrBnW@users.noreply.github.com> Date: Fri, 20 Nov 2020 15:29:21 +0100 Subject: [PATCH] enh(Mikrotik) various enhancements (#2319) --- .../mikrotik/snmp/mode/components/current.pm | 15 +-- network/mikrotik/snmp/mode/components/fan.pm | 44 +++++---- .../snmp/mode/components/{psu.pm => power.pm} | 60 +++--------- .../mikrotik/snmp/mode/components/status.pm | 91 +++++++++++++++++++ .../snmp/mode/components/temperature.pm | 35 +++---- .../mikrotik/snmp/mode/components/voltage.pm | 15 +-- network/mikrotik/snmp/mode/environment.pm | 30 +++--- 7 files changed, 171 insertions(+), 119 deletions(-) rename network/mikrotik/snmp/mode/components/{psu.pm => power.pm} (53%) create mode 100644 network/mikrotik/snmp/mode/components/status.pm diff --git a/network/mikrotik/snmp/mode/components/current.pm b/network/mikrotik/snmp/mode/components/current.pm index 19c257016..8c1d043bc 100644 --- a/network/mikrotik/snmp/mode/components/current.pm +++ b/network/mikrotik/snmp/mode/components/current.pm @@ -41,7 +41,7 @@ sub check_current { ) ); - my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'current', instance => $options{instance}, value => $options{value}); + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'current', instance => $options{name}, value => $options{value}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, @@ -66,28 +66,23 @@ sub check { $self->{components}->{current} = { name => 'current', total => 0, skip => 0 }; return if ($self->check_filter(section => 'current')); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => 0); - - my $gauge_ok = 0; foreach (keys %{$self->{results}}) { next if (! /^$mapping_gauge->{unit}->{oid}\.(\d+)/); next if ($map_gauge_unit->{ $self->{results}->{$_} } ne 'dA'); - - $result = $self->{snmp}->map_instance(mapping => $mapping_gauge, results => $self->{results}, instance => $1); + my $result = $self->{snmp}->map_instance(mapping => $mapping_gauge, results => $self->{results}, instance => $1); + next if ($self->check_filter(section => 'current', instance => $result->{name})); check_current( $self, value => $result->{value} / 10, - instance => $1, name => $result->{name} ); - $gauge_ok = 1; } - if ($gauge_ok == 0 && defined($result->{mtxrHlCurrent}) && $result->{mtxrHlCurrent} =~ /[0-9]+/) { + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => 0); + if (defined($result->{mtxrHlCurrent}) && ! $self->check_filter(section => 'current', instance => 'system')) { check_current( $self, value => $result->{mtxrHlCurrent} / 1000, - instance => 1, name => 'system' ); } diff --git a/network/mikrotik/snmp/mode/components/fan.pm b/network/mikrotik/snmp/mode/components/fan.pm index 233a9b7db..cc2ba4e5c 100644 --- a/network/mikrotik/snmp/mode/components/fan.pm +++ b/network/mikrotik/snmp/mode/components/fan.pm @@ -36,22 +36,23 @@ sub check_fan { $self->{output}->output_add( long_msg => sprintf( - "fan '%s' speed is '%s' RPM", - $options{instance}, + "fan '%s' is %s RPM", + $options{name}, $options{value} ) ); - my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $options{instance}, value => $options{value}); + + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $options{name}, value => $options{value}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, - short_msg => sprintf("Fan '%s' speed is '%s' RPM", $options{instance}, $options{value}) + short_msg => sprintf("Fan '%s' is %s RPM", $options{name}, $options{value}) ); } $self->{output}->perfdata_add( nlabel => 'hardware.fan.speed.rpm', unit => 'rpm', - instances => $options{instance}, + instances => $options{name}, value => $options{value}, warning => $warn, critical => $crit @@ -62,27 +63,36 @@ sub check_fan { sub check { my ($self) = @_; - $self->{output}->output_add(long_msg => "Checking fans"); + $self->{output}->output_add(long_msg => "Checking fan"); $self->{components}->{fan} = { name => 'fans', total => 0, skip => 0 }; return if ($self->check_filter(section => 'fan')); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => 0); - - my $gauge_ok = 0; foreach (keys %{$self->{results}}) { next if (! /^$mapping_gauge->{unit}->{oid}\.(\d+)/); next if ($map_gauge_unit->{ $self->{results}->{$_} } ne 'rpm'); - - $result = $self->{snmp}->map_instance(mapping => $mapping_gauge, results => $self->{results}, instance => $1); - check_fan($self, value => $result->{value}, instance => $result->{name}); - $gauge_ok = 1; + my $result = $self->{snmp}->map_instance(mapping => $mapping_gauge, results => $self->{results}, instance => $1); + next if ($self->check_filter(section => 'fan', instance => $result->{name})); + check_fan( + $self, + value => $result->{value}, + name => $result->{name} + ); } - if ($gauge_ok == 0 && defined($result->{mtxrHlFanSpeed1}) && $result->{mtxrHlFanSpeed1} =~ /[0-9]+/) { - check_fan($self, value => $result->{mtxrHlFanSpeed1}, instance => 1); + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => 0); + if (defined($result->{mtxrHlFanSpeed1}) && ! $self->check_filter(section => 'fan', instance => 'fan1')) { + check_fan( + $self, + value => $result->{mtxrHlFanSpeed1}, + name => 'fan1' + ); } - if ($gauge_ok == 0 && defined($result->{mtxrHlFanSpeed2}) && $result->{mtxrHlFanSpeed2} =~ /[0-9]+/) { - check_fan($self, value => $result->{mtxrHlFanSpeed2}, instance => 2); + if (defined($result->{mtxrHlFanSpeed2}) && ! $self->check_filter(section => 'fan', instance => 'fan2')) { + check_fan( + $self, + value => $result->{mtxrHlFanSpeed2}, + name => 'fan2' + ); } } diff --git a/network/mikrotik/snmp/mode/components/psu.pm b/network/mikrotik/snmp/mode/components/power.pm similarity index 53% rename from network/mikrotik/snmp/mode/components/psu.pm rename to network/mikrotik/snmp/mode/components/power.pm index 9aefced99..d1ef34555 100644 --- a/network/mikrotik/snmp/mode/components/psu.pm +++ b/network/mikrotik/snmp/mode/components/power.pm @@ -18,45 +18,19 @@ # limitations under the License. # -package network::mikrotik::snmp::mode::components::psu; +package network::mikrotik::snmp::mode::components::power; use strict; use warnings; use network::mikrotik::snmp::mode::components::resources qw($map_gauge_unit $mapping_gauge); -my $map_status = { 0 => 'false', 1 => 'true' }; - my $mapping = { - mtxrHlPower => { oid => '.1.3.6.1.4.1.14988.1.1.3.12' }, - mtxrHlPowerSupplyState => { oid => '.1.3.6.1.4.1.14988.1.1.3.15', map => $map_status }, - mtxrHlBackupPowerSupplyState => { oid => '.1.3.6.1.4.1.14988.1.1.3.16', map => $map_status } + mtxrHlPower => { oid => '.1.3.6.1.4.1.14988.1.1.3.12' } }; + sub load {} -sub check_psu { - my ($self, %options) = @_; - - return if (!defined($options{value})); - - $self->{output}->output_add( - long_msg => sprintf( - "psu %s status is '%s'", - $options{type}, $options{value}, - ) - ); - - my $exit = $self->get_severity(section => 'psu.' . $options{type}, value => $options{value}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add( - severity => $exit, - short_msg => sprintf("psu %s status is '%s'", $options{type}, $options{value}) - ); - } - - $self->{components}->{psu}->{total}++; -} - sub check_power { my ($self, %options) = @_; @@ -68,7 +42,7 @@ sub check_power { ) ); - my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'psu', instance => $options{instance}, value => $options{value}); + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'power', instance => $options{name}, value => $options{value}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, @@ -83,41 +57,33 @@ sub check_power { warning => $warn, critical => $crit ); - $self->{components}->{psu}->{total}++; + $self->{components}->{power}->{total}++; } sub check { my ($self) = @_; - $self->{output}->output_add(long_msg => "Checking power supplies"); - $self->{components}->{psu} = {name => 'psu', total => 0, skip => 0}; - return if ($self->check_filter(section => 'psu')); + $self->{output}->output_add(long_msg => "Checking power"); + $self->{components}->{power} = {name => 'power', total => 0, skip => 0}; + return if ($self->check_filter(section => 'power')); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => 0); - - check_psu($self, value => $result->{mtxrHlPowerSupplyState}, type => 'primary'); - check_psu($self, value => $result->{mtxrHlBackupPowerSupplyState}, type => 'backup'); - - my $gauge_ok = 0; foreach (keys %{$self->{results}}) { next if (! /^$mapping_gauge->{unit}->{oid}\.(\d+)/); next if ($map_gauge_unit->{ $self->{results}->{$_} } ne 'dW'); - - $result = $self->{snmp}->map_instance(mapping => $mapping_gauge, results => $self->{results}, instance => $1); + my $result = $self->{snmp}->map_instance(mapping => $mapping_gauge, results => $self->{results}, instance => $1); + next if ($self->check_filter(section => 'power', instance => $result->{name})); check_power( $self, value => $result->{value} / 10, - instance => $1, name => $result->{name} ); - $gauge_ok = 1; } - if ($gauge_ok == 0 && defined($result->{mtxrHlPower}) && $result->{mtxrHlPower} =~ /[0-9]+/) { + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => 0); + if (defined($result->{mtxrHlpower}) && ! $self->check_filter(section => 'power', instance => 'system')) { check_power( $self, - value => $result->{mtxrHlPower} / 10, - instance => 1, + value => $result->{mtxrHlpower} / 10, name => 'system' ); } diff --git a/network/mikrotik/snmp/mode/components/status.pm b/network/mikrotik/snmp/mode/components/status.pm new file mode 100644 index 000000000..e9e753993 --- /dev/null +++ b/network/mikrotik/snmp/mode/components/status.pm @@ -0,0 +1,91 @@ +# +# Copyright 2020 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 network::mikrotik::snmp::mode::components::status; + +use strict; +use warnings; +use network::mikrotik::snmp::mode::components::resources qw($map_gauge_unit $mapping_gauge); + +my $mapping = { + mtxrHlPowerSupplyState => { oid => '.1.3.6.1.4.1.14988.1.1.3.15' }, + mtxrHlBackupPowerSupplyState => { oid => '.1.3.6.1.4.1.14988.1.1.3.16' } +}; + +sub load {} + +sub check_status { + my ($self, %options) = @_; + + $self->{output}->output_add( + long_msg => sprintf( + "status '%s' is %s", + $options{name}, + $options{value} + ) + ); + + my $exit = $self->get_severity(section => 'status', value => $options{value}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Status '%s' is %s", $options{name}, $options{value}) + ); + } + $self->{components}->{status}->{total}++; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking status"); + $self->{components}->{status} = {name => 'status', total => 0, skip => 0}; + return if ($self->check_filter(section => 'status')); + + foreach (keys %{$self->{results}}) { + next if (! /^$mapping_gauge->{unit}->{oid}\.(\d+)/); + next if ($map_gauge_unit->{ $self->{results}->{$_} } ne 'status'); + my $result = $self->{snmp}->map_instance(mapping => $mapping_gauge, results => $self->{results}, instance => $1); + next if ($self->check_filter(section => 'status', instance => $result->{name})); + check_status( + $self, + value => $result->{value} == 0 ? 'ok' : 'not ok', + name => $result->{name} + ); + } + + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => 0); + if (defined($result->{mtxrHlPowerSupplyState}) && ! $self->check_filter(section => 'status', instance => 'psu-primary')) { + check_status( + $self, + value => $result->{mtxrHlPowerSupplyState} == 1 ? 'ok' : 'not ok', + name => 'psu-primary' + ); + } + if (defined($result->{mtxrHlBackupPowerSupplyState}) && ! $self->check_filter(section => 'status', instance => 'psu-backup')) { + check_status( + $self, + value => $result->{mtxrHlBackupPowerSupplyState} == 1 ? 'ok' : 'not ok', + name => 'psu-backup' + ); + } +} + +1; diff --git a/network/mikrotik/snmp/mode/components/temperature.pm b/network/mikrotik/snmp/mode/components/temperature.pm index 6e2ace0fd..dac846aa9 100644 --- a/network/mikrotik/snmp/mode/components/temperature.pm +++ b/network/mikrotik/snmp/mode/components/temperature.pm @@ -36,20 +36,20 @@ sub check_temperature { $self->{output}->output_add( long_msg => sprintf( - "%s is %s C", - $options{description}, + "temperature '%s' is %s C", + $options{name}, $options{value} ) ); - my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $options{instance}, value => $options{value}); - if ($options{value} == -2730) { # RouterOS returns this when the SNMP agent hangs... + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $options{name}, value => $options{value}); + if ($options{value} == -273) { # RouterOS returns this when the SNMP agent hangs... $exit = 'UNKNOWN'; } if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, - short_msg => sprintf("%s is %s C", $options{instance}, $options{value}) + short_msg => sprintf("Temperature '%s' is %s C", $options{name}, $options{value}) ); } $self->{output}->perfdata_add( @@ -70,40 +70,31 @@ sub check { $self->{components}->{temperature} = { name => 'temperature', total => 0, skip => 0 }; return if ($self->check_filter(section => 'temperature')); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => 0); - - my $gauge_ok = 0; foreach (keys %{$self->{results}}) { next if (! /^$mapping_gauge->{unit}->{oid}\.(\d+)/); next if ($map_gauge_unit->{ $self->{results}->{$_} } ne 'celsius'); - - $result = $self->{snmp}->map_instance(mapping => $mapping_gauge, results => $self->{results}, instance => $1); + my $result = $self->{snmp}->map_instance(mapping => $mapping_gauge, results => $self->{results}, instance => $1); + next if ($self->check_filter(section => 'temperature', instance => $result->{name})); check_temperature( $self, value => $result->{value}, - instance => $1, - name => $result->{name}, - description => "sensor temperature '$result->{name}'" + name => $result->{name} ); - $gauge_ok = 1; } - if ($gauge_ok == 0 && defined($result->{mtxrHlTemperature}) && $result->{mtxrHlTemperature} =~ /[0-9]+/) { + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => 0); + if (defined($result->{mtxrHlTemperature}) && ! $self->check_filter(section => 'temperature', instance => 'system')) { check_temperature( $self, value => $result->{mtxrHlTemperature} / 10, - instance => 1, - name => 'system', - description => 'system temperature (SoC or PCB)' + name => 'system' ); } - if ($gauge_ok == 0 && defined($result->{mtxrHlProcessorTemperature}) && $result->{mtxrHlProcessorTemperature} =~ /[0-9]+/) { + if (defined($result->{mtxrHlProcessorTemperature}) && ! $self->check_filter(section => 'temperature', instance => 'processor')) { check_temperature( $self, value => $result->{mtxrHlProcessorTemperature} / 10, - instance => 2, - name => 'processor', - description => 'processor temperature' + name => 'processor' ); } } diff --git a/network/mikrotik/snmp/mode/components/voltage.pm b/network/mikrotik/snmp/mode/components/voltage.pm index e41b688de..5487d2ec3 100644 --- a/network/mikrotik/snmp/mode/components/voltage.pm +++ b/network/mikrotik/snmp/mode/components/voltage.pm @@ -41,7 +41,7 @@ sub check_voltage { ) ); - my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'voltage', instance => $options{instance}, value => $options{value}); + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'voltage', instance => $options{name}, value => $options{value}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( severity => $exit, @@ -66,28 +66,23 @@ sub check { $self->{components}->{voltage} = {name => 'voltage', total => 0, skip => 0}; return if ($self->check_filter(section => 'voltage')); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => 0); - - my $gauge_ok = 0; foreach (keys %{$self->{results}}) { next if (! /^$mapping_gauge->{unit}->{oid}\.(\d+)/); next if ($map_gauge_unit->{ $self->{results}->{$_} } ne 'dV'); - - $result = $self->{snmp}->map_instance(mapping => $mapping_gauge, results => $self->{results}, instance => $1); + my $result = $self->{snmp}->map_instance(mapping => $mapping_gauge, results => $self->{results}, instance => $1); + next if ($self->check_filter(section => 'voltage', instance => $result->{name})); check_voltage( $self, value => $result->{value} / 10, - instance => $1, name => $result->{name} ); - $gauge_ok = 1; } - if ($gauge_ok == 0 && defined($result->{mtxrHlVoltage}) && $result->{mtxrHlVoltage} =~ /[0-9]+/) { + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => 0); + if (defined($result->{mtxrHlVoltage}) && ! $self->check_filter(section => 'voltage', instance => 'system')) { check_voltage( $self, value => $result->{mtxrHlVoltage} / 10, - instance => 1, name => 'system' ); } diff --git a/network/mikrotik/snmp/mode/environment.pm b/network/mikrotik/snmp/mode/environment.pm index 643bfe7a2..1ceabe214 100644 --- a/network/mikrotik/snmp/mode/environment.pm +++ b/network/mikrotik/snmp/mode/environment.pm @@ -28,28 +28,27 @@ use warnings; sub set_system { my ($self, %options) = @_; - $self->{regexp_threshold_numeric_check_section_option} = '^(?:temperature|voltage|fan|current|psu)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(?:current|fan|power|temperature|voltage)$'; $self->{cb_hook2} = 'snmp_execute'; $self->{thresholds} = { - 'psu.primary' => [ - ['true', 'OK'], - ['false', 'CRITICAL'] - ], - 'psu.backup' => [ - ['true', 'OK'], - ['false', 'CRITICAL'] + 'status' => [ + ['not ok', 'CRITICAL'], + ['ok', 'OK'] ] }; $self->{components_path} = 'network::mikrotik::snmp::mode::components'; - $self->{components_module} = ['current', 'fan', 'psu', 'temperature', 'voltage']; + $self->{components_module} = ['current', 'fan', 'power', 'status', 'temperature', 'voltage']; } sub snmp_execute { my ($self, %options) = @_; - my $oid_mtxrHealth = '.1.3.6.1.4.1.14988.1.1.3'; + my $oid_mtxrHealth = '.1.3.6.1.4.1.14988.1.1.3.100.1'; + if (defined($self->{option_results}->{legacy})) { + $oid_mtxrHealth = '.1.3.6.1.4.1.14988.1.1.3'; + } $self->{snmp} = $options{snmp}; $self->{results} = $self->{snmp}->get_table(oid => $oid_mtxrHealth); } @@ -60,6 +59,7 @@ sub new { bless $self, $class; $options{options}->add_options(arguments => { + 'legacy' => { name => 'legacy' } }); return $self; @@ -75,15 +75,19 @@ Check hardware. =over 8 +=item B<--legacy> + +Look for legacy (prior to RouterOS 6.47) OIDs. + =item B<--component> Which component to check (Default: '.*'). -Can be: 'current', 'fan', 'psu', 'temperature', 'voltage'. +Can be: 'current', 'fan', 'power', 'status', 'temperature', 'voltage'. =item B<--filter> Exclude some parts (comma seperated list) (Example: --filter=fan --filter=voltage) -Can also exclude specific instance: --filter=fan,1.1 +Can also exclude specific instance: --filter=fan,fan2 =item B<--no-component> @@ -98,7 +102,7 @@ Example: --warning='temperature,.*,40' =item B<--critical> Set critical threshold for 'temperature', 'fan', 'voltage' (syntax: type,regexp,threshold) -Example: --critical='temperature,.*,50' +Example: --critical='temperature,cpu,50' =back