From 9d0a25c1769f1f6dd7f71407b51c486dad635a8b Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 17 Dec 2015 16:12:08 +0100 Subject: [PATCH] + Enhance cisco wlc ap-status mode --- .../common/airespace/snmp/mode/apstatus.pm | 285 ++++++++++++------ 1 file changed, 187 insertions(+), 98 deletions(-) diff --git a/centreon/common/airespace/snmp/mode/apstatus.pm b/centreon/common/airespace/snmp/mode/apstatus.pm index c3e230234..bc1c60839 100644 --- a/centreon/common/airespace/snmp/mode/apstatus.pm +++ b/centreon/common/airespace/snmp/mode/apstatus.pm @@ -26,58 +26,74 @@ use strict; use warnings; use centreon::plugins::values; -my $maps_counters = { - '0_status' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'opstatus' }, { name => 'admstatus' }, - ], - threshold => 0, - closure_custom_calc => \&custom_status_calc, - closure_custom_output => \&custom_status_output, - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&custom_threshold_output, - } - }, -}; -my $thresholds = { - ap => [ - ['associated', 'OK'], - ['disassociating', 'CRITICAL'], - ['downloading', 'WARNING'], - ], -}; -my $overload_th; +my $instance_mode; -sub get_severity { - my (%options) = @_; - my $status = 'UNKNOWN'; # default - - if (defined($overload_th->{$options{section}})) { - foreach (@{$overload_th->{$options{section}}}) { - if ($options{value} =~ /$_->{filter}/i) { - $status = $_->{status}; - return $status; +my $maps_counters = { + ap => { + '000_status' => { threshold => 0, + set => { + key_values => [ { name => 'opstatus' }, { name => 'admstatus' }, { name => 'display' } ], + threshold => 0, + closure_custom_calc => \&custom_status_calc, + closure_custom_output => \&custom_status_output, + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&custom_threshold_output, } - } + }, + }, + global => { + '000_total' => { set => { + key_values => [ { name => 'total' } ], + output_template => 'Total ap : %s', + perfdatas => [ + { label => 'total', value => 'total_absolute', template => '%s', + min => 0 }, + ], + } + }, + '001_total-associated' => { set => { + key_values => [ { name => 'associated' } ], + output_template => 'Total ap associated : %s', + perfdatas => [ + { label => 'total_associated', value => 'associated_absolute', template => '%s', + min => 0 }, + ], + } + }, + '002_total-disassociating' => { set => { + key_values => [ { name => 'disassociating' } ], + output_template => 'Total ap disassociating : %s', + perfdatas => [ + { label => 'total_disassociating', value => 'disassociating_absolute', template => '%s', + min => 0 }, + ], + } + }, } - foreach (@{$thresholds->{$options{section}}}) { - if ($options{value} =~ /$$_[0]/i) { - $status = $$_[1]; - return $status; - } - } - - return $status; -} +}; sub custom_threshold_output { - my ($self, %options) = @_; + my ($self, %options) = @_; + my $status = 'ok'; + my $message; - if ($self->{result_values}->{admstatus} eq 'disabled') { - return 'ok'; + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); } - return get_severity(section => 'ap', value => $self->{result_values}->{opstatus}); + + return $status; } sub custom_status_output { @@ -98,6 +114,7 @@ sub custom_status_calc { $self->{result_values}->{opstatus} = $options{new_datas}->{$self->{instance} . '_opstatus'}; $self->{result_values}->{admstatus} = $options{new_datas}->{$self->{instance} . '_admstatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; return 0; } @@ -110,21 +127,23 @@ sub new { $options{options}->add_options(arguments => { "filter-name:s" => { name => 'filter_name' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{admstatus} eq "enable" and %{opstatus} !~ /associated|downloading/' }, }); - foreach (keys %{$maps_counters}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$_}->{threshold}) || $maps_counters->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); + foreach my $key (('global', 'ap')) { + foreach (keys %{$maps_counters->{$key}}) { + my ($id, $name) = split /_/; + if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { + $options{options}->add_options(arguments => { + 'warning-' . $name . ':s' => { name => 'warning-' . $name }, + 'critical-' . $name . ':s' => { name => 'critical-' . $name }, + }); + } + $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, + label => $name); + $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); } - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); } return $self; @@ -134,59 +153,42 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - $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(); + foreach my $key (('global', 'ap')) { + foreach (keys %{$maps_counters->{$key}}) { + $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); } - my ($section, $status, $filter) = ('ap', $1, $2); - 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(); - } - $overload_th->{$section} = [] if (!defined($overload_th->{$section})); - push @{$overload_th->{$section}}, {filter => $filter, status => $status}; } + + $instance_mode = $self; + $self->change_macros(); } -sub run { +sub run_instance { my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - my $multiple = 1; - if (scalar(keys %{$self->{ap_selected}}) <= 1) { - $multiple = 0; - } - - if ($multiple == 1) { + if ($self->{multiple} == 1) { $self->{output}->output_add(severity => 'OK', short_msg => 'All AP status are ok'); } - foreach my $id ($self->{snmp}->oid_lex_sort(keys %{$self->{ap_selected}})) { + foreach my $id (sort keys %{$self->{ap_selected}}) { my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => $id); + my @exits = (); + foreach (sort keys %{$maps_counters->{ap}}) { + my $obj = $maps_counters->{ap}->{$_}->{obj}; + $obj->set(instance => $id); - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{ap_selected}->{$id}); + my ($value_check) = $obj->execute(values => $self->{ap_selected}->{$id}); if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); + $long_msg .= $long_msg_append . $obj->output_error(); $long_msg_append = ', '; next; } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); + my $exit2 = $obj->threshold_check(); push @exits, $exit2; - my $output = $maps_counters->{$_}->{obj}->output(); + my $output = $obj->output(); $long_msg .= $long_msg_append . $output; $long_msg_append = ', '; @@ -195,7 +197,7 @@ sub run { $short_msg_append = ', '; } - $maps_counters->{$_}->{obj}->perfdata(extra_instance => $multiple); + $obj->perfdata(extra_instance => $self->{multiple}); } $self->{output}->output_add(long_msg => "AP '" . $self->{ap_selected}->{$id}->{display} . "' $long_msg"); @@ -206,15 +208,80 @@ sub run { ); } - if ($multiple == 0) { + if ($self->{multiple} == 0) { $self->{output}->output_add(short_msg => "AP '" . $self->{ap_selected}->{$id}->{display} . "' $long_msg"); } } +} + +sub run_global { + my ($self, %options) = @_; + + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits; + foreach (sort keys %{$maps_counters->{global}}) { + my $obj = $maps_counters->{global}->{$_}->{obj}; + + $obj->set(instance => 'global'); + + my ($value_check) = $obj->execute(values => $self->{global}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $obj->output_error(); + $long_msg_append = ', '; + next; + } + my $exit2 = $obj->threshold_check(); + push @exits, $exit2; + + my $output = $obj->output(); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + + if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + $obj->perfdata(); + } + + my $exit = $self->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => "$short_msg" + ); + } else { + $self->{output}->output_add(short_msg => "$long_msg"); + } +} + +sub run { + my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; + + $self->manage_selection(); + + if ($self->{multiple} == 1) { + $self->run_global(); + } + + $self->run_instance(); $self->{output}->display(); $self->{output}->exit(); } +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + my %map_admin_status = ( 1 => 'enable', 2 => 'disable', @@ -233,13 +300,13 @@ my $mapping2 = { my $mapping3 = { bsnAPAdminStatus => { oid => '.1.3.6.1.4.1.14179.2.2.1.1.37', map => \%map_admin_status }, }; - my $oid_agentInventoryMachineModel = '.1.3.6.1.4.1.14179.1.1.1.3'; sub manage_selection { my ($self, %options) = @_; $self->{ap_selected} = {}; + $self->{global} = { total => 0, associated => 0, disassociating => 0, downloading => 0 }; $self->{results} = $self->{snmp}->get_multiple_table(oids => [ { oid => $oid_agentInventoryMachineModel }, { oid => $mapping->{bsnAPName}->{oid} }, { oid => $mapping2->{bsnAPOperationStatus}->{oid} }, @@ -259,6 +326,9 @@ sub manage_selection { next; } + $self->{global}->{total}++; + $self->{global}->{$result2->{bsnAPOperationStatus}}++; + $self->{ap_selected}->{$instance} = { display => $result->{bsnAPName}, opstatus => $result2->{bsnAPOperationStatus}, admstatus => $result3->{bsnAPAdminStatus}}; } @@ -267,6 +337,11 @@ sub manage_selection { $self->{output}->output_add(severity => 'OK', short_msg => 'No AP associated (can be: slave wireless controller or your filter)'); } + + $self->{multiple} = 1; + if (scalar(keys %{$self->{ap_selected}}) <= 1) { + $self->{multiple} = 0; + } } 1; @@ -283,11 +358,25 @@ Check AP status. Filter AP name (can be a regexp). -=item B<--threshold-overload> +=item B<--warning-status> -Set to overload default ap threshold values (syntax: status,regexp) -It used before default thresholds (order stays). -Example: --threshold-overload='CRITICAL,^(?!(associated)$)' +Set warning threshold for status. +Can used special variables like: %{admstatus}, %{opstatus}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{admstatus} eq "enable" and %{opstatus} !~ /associated|downloading/'). +Can used special variables like: %{admstatus}, %{opstatus}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total', 'total-associated', 'total-disassociating'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total', 'total-associated', 'total-disassociating'. =back