From e6248a99f829f2b1c580f0b85aa719d9c473ca88 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 11 May 2021 16:17:40 +0200 Subject: [PATCH] enh(printers/standard/snmp): add endian option for printers-errors + refactoring of cover-status mode (#2786) --- .../standard/rfc3805/mode/coverstatus.pm | 118 ++++++++++------ .../snmp_standard/mode/printererror.pm | 128 ++++++++++-------- 2 files changed, 148 insertions(+), 98 deletions(-) diff --git a/centreon-plugins/hardware/printers/standard/rfc3805/mode/coverstatus.pm b/centreon-plugins/hardware/printers/standard/rfc3805/mode/coverstatus.pm index 18a7da8b0..6dc3eb0bb 100644 --- a/centreon-plugins/hardware/printers/standard/rfc3805/mode/coverstatus.pm +++ b/centreon-plugins/hardware/printers/standard/rfc3805/mode/coverstatus.pm @@ -20,65 +20,82 @@ package hardware::printers::standard::rfc3805::mode::coverstatus; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::misc; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); -my %cover_status = ( - 1 => ["'%s' status is other", 'UNKNOWN'], - 3 => ["Cover '%s' status is open", 'WARNING'], - 4 => ["Cover '%s' status is closed", 'OK'], - 5 => ["Interlock '%s' status is open", 'WARNING'], - 6 => ["Interlock '%s' status is closed", 'WARNING'], -); +sub prefix_cover_output { + my ($self, %options) = @_; + + return "Cover '" . $options{instance_value}->{description} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'covers', type => 1, cb_prefix_output => 'prefix_cover_output', message_multiple => 'All covers are ok' } + ]; + + $self->{maps_counters}->{covers} = [ + { + label => 'status', + type => 2, + unknown_default => '%{status} =~ /other|unknown/', + warning_default => '%{status} =~ /coverOpen|interlockOpen/', + set => { + key_values => [ { name => 'status' }, { name => 'description' } ], + output_template => "status is '%s'", + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - - $options{options}->add_options(arguments => - { - }); + + $options{options}->add_options(arguments => { + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); -} +my $map_status = { + 1 => 'other', 2 => 'unknown', + 3 => 'coverOpen', 4 => 'coverClosed', + 5 => 'interlockOpen', 6 => 'interlockClosed' +}; -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; +my $mapping = { + description => { oid => '.1.3.6.1.2.1.43.6.1.1.2' }, # prtCoverDescription + status => { oid => '.1.3.6.1.2.1.43.6.1.1.3', map => $map_status } # prtCoverStatus +}; - $self->{output}->output_add(severity => 'OK', - short_msg => "All covers/interlocks are ok."); - - my $oid_prtCoverEntry = '.1.3.6.1.2.1.43.6.1.1'; - my $oid_prtCoverDescription = '.1.3.6.1.2.1.43.6.1.1.2'; - my $oid_prtCoverStatus = '.1.3.6.1.2.1.43.6.1.1.3'; - my $result = $self->{snmp}->get_table(oid => $oid_prtCoverEntry, nothing_quit => 1); - - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /^$oid_prtCoverStatus\.(\d+).(\d+)/); - my ($hrDeviceIndex, $prtCoverIndex) = ($1, $2); - my $instance = $hrDeviceIndex . '.' . $prtCoverIndex; - my $status = $result->{$oid_prtCoverStatus . '.' . $instance}; - my $descr = centreon::plugins::misc::trim($result->{$oid_prtCoverDescription . '.' . $instance}); - - $self->{output}->output_add(long_msg => sprintf(${$cover_status{$status}}[0], $descr)); - if (!$self->{output}->is_status(value => ${$cover_status{$status}}[1], compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => ${$cover_status{$status}}[1], - short_msg => sprintf(${$cover_status{$status}}[0], $descr)); - } +sub manage_selection { + my ($self, %options) = @_; + + my $oid_prtCoverTable = '.1.3.6.1.2.1.43.6.1'; + my $snmp_result = $options{snmp}->get_table( + oid => $oid_prtCoverTable, + start => $mapping->{description}->{oid}, + nothing_quit => 1 + ); + + $self->{covers} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{status}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + $result->{description} = centreon::plugins::misc::trim($result->{description}); + $self->{covers}->{$instance} = $result; } - - $self->{output}->display(); - $self->{output}->exit(); } 1; @@ -87,10 +104,25 @@ __END__ =head1 MODE -Check covers and interlocks of the printer. +Check covers of the printer. =over 8 +=item B<--unknown-status> + +Set unknown threshold for status (Default: '%%{status} =~ /other|unknown/'). +Can used special variables like: %{status}, %{description} + +=item B<--warning-status> + +Set warning threshold for status (Default: '%%{status} =~ /coverOpen|interlockOpen/'). +Can used special variables like: %{status}, %{description} + +=item B<--critical-status> + +Set critical threshold for status. +Can used special variables like: %{status}, %{description} + =back =cut diff --git a/centreon-plugins/snmp_standard/mode/printererror.pm b/centreon-plugins/snmp_standard/mode/printererror.pm index d282e3d9b..717bba720 100644 --- a/centreon-plugins/snmp_standard/mode/printererror.pm +++ b/centreon-plugins/snmp_standard/mode/printererror.pm @@ -26,37 +26,6 @@ use strict; use warnings; use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); -sub custom_status_calc { - my ($self, %options) = @_; - - $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; - return 0; -} - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'printer', type => 3, cb_prefix_output => 'prefix_printer_output', cb_long_output => 'printer_long_output', indent_long_output => ' ', message_multiple => 'All printers are ok', - group => [ - { name => 'errors', message_multiple => 'Printer is ok', type => 1, skipped_code => { -10 => 1 } }, - ] - } - ]; - - $self->{maps_counters}->{errors} = [ - { label => 'status', threshold => 0, set => { - key_values => [ { name => 'status' } ], - closure_custom_calc => $self->can('custom_status_calc'), - output_template => "status is '%s'", - output_use => 'status', - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&catalog_status_threshold, - } - }, - ]; -} - sub prefix_printer_output { my ($self, %options) = @_; @@ -69,16 +38,39 @@ sub printer_long_output { return "checking printer '" . $options{instance_value}->{display} . "'"; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'printer', type => 3, cb_prefix_output => 'prefix_printer_output', cb_long_output => 'printer_long_output', indent_long_output => ' ', message_multiple => 'All printers are ok', + group => [ + { name => 'errors', message_multiple => 'Printer is ok', type => 1, skipped_code => { -10 => 1 } } + ] + } + ]; + + $self->{maps_counters}->{errors} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' } ], + output_template => "status is '%s'", + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold + } + } + ]; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $options{options}->add_options(arguments => { + $options{options}->add_options(arguments => { + 'big-endian' => { name => 'big_endian' }, 'ok-status:s' => { name => 'ok_status', default => '%{status} =~ /ok/' }, 'unknown-status:s' => { name => 'unknown_status', default => '' }, 'warning-status:s' => { name => 'warning_status', default => '%{status} =~ /.*/' }, - 'critical-status:s' => { name => 'critical_status', default => '' }, + 'critical-status:s' => { name => 'critical_status', default => '' } }); return $self; @@ -91,23 +83,42 @@ sub check_options { $self->change_macros(macros => ['ok_status', 'unknown_status', 'warning_status', 'critical_status']); } -my %errors_printer = ( - 0 => 'low paper', - 1 => 'no paper', - 2 => 'low toner', - 3 => 'no toner', - 4 => 'door open', - 5 => 'jammed', - 6 => 'offline', - 7 => 'service requested', - 8 => 'input tray missing', - 9 => 'output tray missing', - 10 => 'maker supply missing', - 11 => 'output near full', - 12 => 'output full', - 13 => 'input tray empty', - 14 => 'overdue prevent maint', -); +my $errors_printer = { + normal => { + 0 => 'low paper', + 1 => 'no paper', + 2 => 'low toner', + 3 => 'no toner', + 4 => 'door open', + 5 => 'jammed', + 6 => 'offline', + 7 => 'service requested', + 8 => 'input tray missing', + 9 => 'output tray missing', + 10 => 'maker supply missing', + 11 => 'output near full', + 12 => 'output full', + 13 => 'input tray empty', + 14 => 'overdue prevent maint' + }, + bigendian => { + 7 => 'low paper', + 6 => 'no paper', + 5 => 'low toner', + 4 => 'no toner', + 3 => 'door open', + 2 => 'jammed', + 1 => 'offline', + 0 => 'service requested', + 14 => 'input tray missing', + 13 => 'output tray missing', + 12 => 'maker supply missing', + 11 => 'output near full', + 10 => 'output full', + 9 => 'input tray empty', + 8 => 'overdue prevent maint' + } +}; sub manage_selection { my ($self, %options) = @_; @@ -115,6 +126,9 @@ sub manage_selection { my $oid_hrPrinterDetectedErrorState = '.1.3.6.1.2.1.25.3.5.1.2'; my $result = $options{snmp}->get_table(oid => $oid_hrPrinterDetectedErrorState, nothing_quit => 1); + my $label_errors = 'normal'; + $label_errors = 'bigendian' if (defined($self->{option_results}->{big_endian})); + $self->{printer} = {}; foreach (keys %$result) { /\.(\d+)$/; @@ -127,13 +141,13 @@ sub manage_selection { $self->{printer}->{$instance} = { display => $instance, errors => {} }; my $i = 0; - foreach my $key (keys %errors_printer) { + foreach my $key (keys %{$errors_printer->{$label_errors}}) { if (($value & (1 << $key))) { - $self->{printer}->{$instance}->{errors}->{$i} = { status => $errors_printer{$key} }; + $self->{printer}->{$instance}->{errors}->{$i} = { status => $errors_printer->{$label_errors}->{$key} }; $i++; } } - + if ($i == 0) { $self->{printer}->{$instance}->{errors}->{0} = { status => 'ok' }; next; @@ -151,6 +165,10 @@ Check printer errors (HOST-RESOURCES-MIB). =over 8 +=item B<--big-endian> + +Use that option if your printer provides big-endian bits ordering. + =item B<--ok-status> Set warning threshold for status (Default: '%{status} =~ /ok/'). @@ -158,7 +176,7 @@ Can used special variables like: %{status} =item B<--unknown-status> -Set warning threshold for status (Default: ''). +Set unknown threshold for status. Can used special variables like: %{status} =item B<--warning-status> @@ -168,7 +186,7 @@ Can used special variables like: %{status} =item B<--critical-status> -Set critical threshold for status (Default: ''). +Set critical threshold for status. Can used special variables like: %{status} =back