From 8cba2fd80b0c05510499e69c66291717d7304af5 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Mon, 17 Aug 2015 15:06:11 +0200 Subject: [PATCH] + Add atrica plugin (WIP) --- network/atrica/snmp/mode/connections.pm | 447 ++++++++++++++++++++++++ network/atrica/snmp/plugin.pm | 49 +++ snmp_standard/mode/interfaces.pm | 8 +- 3 files changed, 500 insertions(+), 4 deletions(-) create mode 100644 network/atrica/snmp/mode/connections.pm create mode 100644 network/atrica/snmp/plugin.pm diff --git a/network/atrica/snmp/mode/connections.pm b/network/atrica/snmp/mode/connections.pm new file mode 100644 index 000000000..3960a4adf --- /dev/null +++ b/network/atrica/snmp/mode/connections.pm @@ -0,0 +1,447 @@ +# +# Copyright 2015 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::atrica::snmp::mode::connections; + +use base qw(snmp_standard::mode::interfaces); + +use strict; +use warnings; + +my $instance_mode; + +sub set_oids_label { + my ($self, %options) = @_; + + $self->{oids_label} = { + 'atrconncepgendescr' => '.1.3.6.1.4.1.6110.2.7.5.1.1', + 'atrconningdescr' => '.1.3.6.1.4.1.6110.2.2.1.1.2', + }; +} + +sub set_oids_status { + my ($self, %options) = @_; + + if ($self->{option_results}->{oid_filter} eq 'atrconncepgendescr') { + $self->{oid_adminstatus} = '.1.3.6.1.4.1.6110.2.7.5.1.7'; + $self->{oid_adminstatus_mapping} = { + 1 => 'up', 2 => 'down', + }; + $self->{oid_opstatus} = '.1.3.6.1.4.1.6110.2.7.5.1.8'; + $self->{oid_opstatus_mapping} = { + 1 => 'up', 2 => 'down', 3 => 'oneWay', 4 => 'twoWay', 5 => 'fastProtected', + }; + if (!defined($self->{option_results}->{critical_status})) { + $self->{option_results}->{critical_status} = '%{admstatus} eq "up" and %{opstatus} ne "up"'; + } + } else { + $self->{oid_adminstatus} = '.1.3.6.1.4.1.6110.2.2.1.1.3'; + $self->{oid_adminstatus_mapping} = { + 2 => 'off', 3 => 'on', + }; + $self->{oid_opstatus} = '.1.3.6.1.4.1.6110.2.2.1.1.4'; + $self->{oid_opstatus_mapping} = { + 2 => 'off', 3 => 'systemBusy', 4 => 'dependencyBusy', 5 => 'inService', 6 => 'alterInService', 7 => 'failed', + 8 => 'mainInServiceViaCoreLinkProtec', 9 => 'alterInServiceViaCoreLinkProtec', + 10 => 'mainAndAltDownConnUpSendingToMain', 11 => 'mainAndAltDownConnUpSendingToAlt', + }; + if (!defined($self->{option_results}->{critical_status})) { + $self->{option_results}->{critical_status} = '%{admstatus} eq "on" and %{opstatus} ne "inService"'; + } + } +} + +sub set_speed { + my ($self, %options) = @_; + + $self->{oid_speed} = '.1.3.6.1.4.1.6110.2.9.1.1.14'; # in Kb/s +} + +sub set_oids_errors { + my ($self, %options) = @_; + + $self->{oid_ing_eir_discard} = '.1.3.6.1.4.1.6110.2.2.4.1.1.7'; # in B + $self->{oid_eg_eir_discard} = '.1.3.6.1.4.1.6110.2.3.2.1.1.6'; # in B +} + +sub set_oids_traffic { + my ($self, %options) = @_; + + $self->{oid_ing_cir} = '.1.3.6.1.4.1.6110.2.2.4.1.1.4'; # in B + $self->{oid_ing_eir} = '.1.3.6.1.4.1.6110.2.2.4.1.1.5'; # in B + $self->{oid_eg_cir} = '.1.3.6.1.4.1.6110.2.3.2.1.1.4'; # in B + $self->{oid_eg_eir} = '.1.3.6.1.4.1.6110.2.3.2.1.1.5'; # in B +} + +sub default_warning_status { + my ($self, %options) = @_; + + return undef; +} + +sub default_critical_status { + my ($self, %options) = @_; + + return undef; +} + +sub default_oid_filter_name { + my ($self, %options) = @_; + + return 'atrConnCepGenDescr'; +} + +sub default_oid_display_name { + my ($self, %options) = @_; + + return 'atrConnCepGenDescr'; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters} = { int => {}, global => {} }; + $self->{maps_counters}->{int}->{'030_in-cir'} = { filter => 'add_traffic', + set => { + key_values => [ { name => 'in_cir', diff => 1 }, { name => 'speed_in'}, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'in_cir' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic In CIR : %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }; + $self->{maps_counters}->{int}->{'031_in-eir'} = { filter => 'add_traffic', + set => { + key_values => [ { name => 'in_eir', diff => 1 }, { name => 'speed_in'}, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'in_eir' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic In EIR : %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }; + $self->{maps_counters}->{int}->{'032_out-cir'} = { filter => 'add_traffic', + set => { + key_values => [ { name => 'out_cir', diff => 1 }, { name => 'speed_out'}, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'out_cir' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic Out CIR : %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }; + $self->{maps_counters}->{int}->{'033_out-eir'} = { filter => 'add_traffic', + set => { + key_values => [ { name => 'out_eir', diff => 1 }, { name => 'speed_out'}, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'out_eir' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic Out EIR : %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }; + $self->{maps_counters}->{int}->{'050_in-eir-discard'} = { filter => 'add_errors', + set => { + key_values => [ { name => 'in_eir_discard', diff => 1 }, { name => 'speed_in'}, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'in_eir_discard' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic In EIR Discard : %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }; + $self->{maps_counters}->{int}->{'051_out-eir-discard'} = { filter => 'add_errors', + set => { + key_values => [ { name => 'out_eir_discard', diff => 1 }, { name => 'speed_out'}, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'out_eir_discard' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic Out EIR Discard : %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }; + + $self->SUPER::set_counters(%options); +} + +sub custom_traffic_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { + $extra_label .= '_' . $self->{result_values}->{display}; + } + + my ($warning, $critical); + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}); + } + + $self->{output}->perfdata_add(label => $self->{result_values}->{label} . $extra_label, unit => 'b/s', + value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed}); +} + +sub custom_traffic_threshold { + my ($self, %options) = @_; + + my $exit = 'ok'; + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_per_seconds}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } + return $exit; +} + +sub custom_traffic_output { + my ($self, %options) = @_; + + my $label = $self->{result_values}->{label}; + $label =~ s/_/ /g; + $label =~ s/(\w+)/\u$1/g; + my ($traffic_value, $traffic_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{traffic_per_seconds}, network => 1); + my $msg = sprintf("Traffic %s : %s/s (%s)", + $label, $traffic_value . $traffic_unit, + defined($self->{result_values}->{traffic_prct}) ? sprintf("%.2f%%", $self->{result_values}->{traffic_prct}) : '-'); + return $msg; +} + +sub custom_traffic_calc { + my ($self, %options) = @_; + + my $diff_traffic = ($options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}} - $options{old_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}}); + if ($diff_traffic == 0) { + $self->{error_msg} = "skipped"; + return -2; + } + + $self->{result_values}->{traffic_per_seconds} = $diff_traffic / $options{delta_time}; + if (defined($options{new_datas}->{$self->{instance} . '_speed_' . $options{extra_options}->{label_ref}}) && + $options{new_datas}->{$self->{instance} . '_speed_' . $options{extra_options}->{label_ref}} > 0) { + $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic_per_seconds} * 100 / $options{new_datas}->{$self->{instance} . '_speed_' . $options{extra_options}->{label_ref}}; + $self->{result_values}->{speed} = $options{new_datas}->{$self->{instance} . '_speed_' . $options{extra_options}->{label_ref}}; + } + + $self->{result_values}->{label} = $options{extra_options}->{label_ref}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, + no_set_traffic => 1, no_set_errors => 1, no_cast => 1); + bless $self, $class; + + $instance_mode = $self; + return $self; +} + +sub load_speed { + my ($self, %options) = @_; + + $self->{speed_loaded} = 1; + $self->{snmp}->load(oids => [$self->{oid_speed}], instances => $self->{array_interface_selected}); +} + +sub load_traffic { + my ($self, %options) = @_; + + if (!$self->{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Can't check SNMP 64 bits counters with SNMPv1."); + $self->{output}->option_exit(); + } + + if (!defined($self->{speed_loaded})) { + $self->set_speed(); + $self->load_speed(); + } + $self->set_oids_traffic(); + $self->{snmp}->load(oids => [$self->{oid_ing_cir}, $self->{oid_ing_eir}, + $self->{oid_eg_cir}, $self->{oid_eg_eir}], instances => $self->{array_interface_selected}); +} + +sub load_errors { + my ($self, %options) = @_; + + if (!$self->{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Can't check SNMP 64 bits counters with SNMPv1."); + $self->{output}->option_exit(); + } + if (!defined($self->{speed_loaded})) { + $self->set_speed(); + $self->load_speed(); + } + $self->set_oids_errors(); + $self->{snmp}->load(oids => [$self->{oid_ing_eir_discard}, $self->{oid_eg_eir_discard}], instances => $self->{array_interface_selected}); +} + +sub add_result_speed { + my ($self, %options) = @_; + + $self->{interface_selected}->{$options{instance}}->{speed_in} = 0; + $self->{interface_selected}->{$options{instance}}->{speed_out} = 0; + if ($self->{get_speed} == 0) { + if (defined($self->{option_results}->{speed}) && $self->{option_results}->{speed} ne '') { + $self->{interface_selected}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed} * 1000000; + $self->{interface_selected}->{$options{instance}}->{speed_out} = $self->{option_results}->{speed} * 1000000; + } + $self->{interface_selected}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed_in} * 1000000 if (defined($self->{option_results}->{speed_in}) && $self->{option_results}->{speed_in} ne ''); + $self->{interface_selected}->{$options{instance}}->{speed_out} = $self->{option_results}->{speed_out} * 1000000 if (defined($self->{option_results}->{speed_out}) && $self->{option_results}->{speed_out} ne ''); + } else { + my $interface_speed = 0; + $interface_speed = $self->{results}->{$self->{oid_speed} . "." . $options{instance}} * 1000; + $self->{interface_selected}->{$options{instance}}->{speed_in} = $interface_speed; + $self->{interface_selected}->{$options{instance}}->{speed_out} = $interface_speed; + $self->{interface_selected}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed_in} * 1000000 if (defined($self->{option_results}->{speed_in}) && $self->{option_results}->{speed_in} ne ''); + $self->{interface_selected}->{$options{instance}}->{speed_out} = $self->{option_results}->{speed_out} * 1000000 if (defined($self->{option_results}->{speed_out}) && $self->{option_results}->{speed_out} ne ''); + } +} + +sub add_result_errors { + my ($self, %options) = @_; + + $self->{interface_selected}->{$options{instance}}->{in_eir_discard} = $self->{results}->{$self->{oid_ing_eir_discard} . '.' . $options{instance}} * 8; + $self->{interface_selected}->{$options{instance}}->{out_eir_discard} = $self->{results}->{$self->{oid_eg_eir_discard} . '.' . $options{instance}} * 8; + $self->add_result_speed(); +} + +sub add_result_traffic { + my ($self, %options) = @_; + + $self->{interface_selected}->{$options{instance}}->{in_cir} = $self->{results}->{$self->{oid_ing_cir} . '.' . $options{instance}} * 8; + $self->{interface_selected}->{$options{instance}}->{in_eir} = $self->{results}->{$self->{oid_ing_eir} . '.' . $options{instance}} * 8; + $self->{interface_selected}->{$options{instance}}->{out_cir} = $self->{results}->{$self->{oid_eg_cir} . '.' . $options{instance}} * 8; + $self->{interface_selected}->{$options{instance}}->{out_eir} = $self->{results}->{$self->{oid_eg_eir} . '.' . $options{instance}} * 8; + $self->add_result_speed(); +} + +1; + +__END__ + +=head1 MODE + +Check connections. + +=over 8 + +=item B<--add-status> + +Check interface status (By default if no --add-* option is set). + +=item B<--add-traffic> + +Check interface traffic. + +=item B<--add-errors> + +Check interface errors. + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{admstatus}, %{opstatus}, %{display} + +=item B<--critical-status> + +Set critical threshold for status. +Default (depends of the atrica release): +'%{admstatus} eq "on" and %{opstatus} ne "inService"' +'%{admstatus} eq "up" and %{opstatus} ne "up"' +Can used special variables like: %{admstatus}, %{opstatus}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'in-cir', 'in-eir', 'out-cir', 'out-eir', 'in-eir-discard', 'out-eir-discard'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'in-cir', 'in-eir', 'out-cir', 'out-eir', 'in-eir-discard', 'out-eir-discard'. + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: '%') ('%', 'b/s'). + +=item B<--units-errors> + +Units of thresholds for discards (Default: '%') ('%', 'b/s'). + +=item B<--interface> + +Set the interface (number expected) ex: 1,2,... (empty means 'check all interface'). + +=item B<--name> + +Allows to use interface name with option --interface instead of interface oid index (Can be a regexp) + +=item B<--speed> + +Set interface speed for incoming/outgoing traffic (in Mb). + +=item B<--speed-in> + +Set interface speed for incoming traffic (in Mb). + +=item B<--speed-out> + +Set interface speed for outgoing traffic (in Mb). + +=item B<--reload-cache-time> + +Time in seconds before reloading cache file (default: 180). + +=item B<--oid-filter> + +Choose OID used to filter interface (default: atrConnCepGenDescr) (values: atrConnIngDescr, atrConnCepGenDescr). + +=item B<--oid-display> + +Choose OID used to display interface (default: atrConnCepGenDescr) (values: atrConnIngDescr, atrConnCepGenDescr). + +=item B<--oid-extra-display> + +Add an OID to display. + +=item B<--display-transform-src> + +Regexp src to transform display value. + +=item B<--display-transform-dst> + +Regexp dst to transform display value. + +=item B<--show-cache> + +Display cache interface datas. + +=back + +=cut diff --git a/network/atrica/snmp/plugin.pm b/network/atrica/snmp/plugin.pm new file mode 100644 index 000000000..fa4737402 --- /dev/null +++ b/network/atrica/snmp/plugin.pm @@ -0,0 +1,49 @@ +# +# Copyright 2015 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::atrica::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'connections' => 'network::atrica::snmp::mode::connections', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Atrica equipments in SNMP. + +=cut diff --git a/snmp_standard/mode/interfaces.pm b/snmp_standard/mode/interfaces.pm index 5892fc699..e4151f01c 100644 --- a/snmp_standard/mode/interfaces.pm +++ b/snmp_standard/mode/interfaces.pm @@ -256,7 +256,7 @@ sub custom_errors_calc { sub set_counters { my ($self, %options) = @_; - $self->{maps_counters} = { int => {}, global => {} }; + $self->{maps_counters} = { int => {}, global => {} } if (!defined($self->{maps_counters})); $self->{maps_counters}->{int}->{'000_status'} = { filter => 'add_status', threshold => 0, set => { key_values => $self->set_key_values_status(), @@ -638,7 +638,7 @@ sub check_options { $self->{output}->option_exit(); } if (defined($self->{option_results}->{add_errors}) && - (!defined($self->{option_results}->{units_errors}) || $self->{option_results}->{units_errors} !~ /^(%|absolute)$/)) { + (!defined($self->{option_results}->{units_errors}) || $self->{option_results}->{units_errors} !~ /^(%|absolute|b\/s)$/)) { $self->{output}->add_option_msg(short_msg => "Wrong option --units-errors."); $self->{output}->option_exit(); } @@ -936,14 +936,14 @@ sub get_informations { $self->load_status() if (defined($self->{option_results}->{add_status})); $self->load_errors() if (defined($self->{option_results}->{add_errors})); $self->load_traffic() if (defined($self->{option_results}->{add_traffic})); - $self->load_cast() if (defined($self->{option_results}->{add_cast}) || defined($self->{option_results}->{add_errors})); + $self->load_cast() if ($self->{no_cast} == 0 && (defined($self->{option_results}->{add_cast}) || defined($self->{option_results}->{add_errors}))); $self->{results} = $self->{snmp}->get_leef(); foreach (@{$self->{array_interface_selected}}) { $self->add_result_status(instance => $_) if (defined($self->{option_results}->{add_status})); $self->add_result_traffic(instance => $_) if (defined($self->{option_results}->{add_traffic})); - $self->add_result_cast(instance => $_) if (defined($self->{option_results}->{add_cast}) || defined($self->{option_results}->{add_errors})); + $self->add_result_cast(instance => $_) if ($self->{no_cast} == 0 && (defined($self->{option_results}->{add_cast}) || defined($self->{option_results}->{add_errors}))); $self->add_result_errors(instance => $_) if (defined($self->{option_results}->{add_errors})); } }