From e3769e6f7650818191ac66ff964e1f4a944fd4ba Mon Sep 17 00:00:00 2001 From: qgarnier Date: Mon, 24 Jul 2017 12:37:31 +0200 Subject: [PATCH] add mode for nokia timos --- network/nokia/timos/snmp/mode/l2tpusage.pm | 352 +++++++++++++++++++++ network/nokia/timos/snmp/mode/listldp.pm | 2 +- network/nokia/timos/snmp/mode/listvrtr.pm | 130 ++++++++ network/nokia/timos/snmp/plugin.pm | 2 + 4 files changed, 485 insertions(+), 1 deletion(-) create mode 100644 network/nokia/timos/snmp/mode/l2tpusage.pm create mode 100644 network/nokia/timos/snmp/mode/listvrtr.pm diff --git a/network/nokia/timos/snmp/mode/l2tpusage.pm b/network/nokia/timos/snmp/mode/l2tpusage.pm new file mode 100644 index 000000000..580fb419a --- /dev/null +++ b/network/nokia/timos/snmp/mode/l2tpusage.pm @@ -0,0 +1,352 @@ +# +# Copyright 2017 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::nokia::timos::snmp::mode::l2tpusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use Socket; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + 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 $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'state : ' . $self->{result_values}->{state}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + + +sub custom_total_sessions_calc { + my ($self, %options) = @_; + + my $total_sessions = 0; + foreach (keys %{$options{new_datas}}) { + if (/$self->{instance}_total_sessions_(\d+)/) { + my $new_total = $options{new_datas}->{$_}; + next if (!defined($options{old_datas}->{$_})); + my $old_total = $options{old_datas}->{$_}; + + $total_sessions += $new_total - $old_total; + $total_sessions += $old_total if ($total_sessions <= 0); + } + } + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total_sessions} = $total_sessions; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'tunnel', type => 1, cb_prefix_output => 'prefix_tunnel_output', message_multiple => 'All tunnels are ok' }, + { name => 'vrtr', type => 1, cb_prefix_output => 'prefix_vrtr_output', message_multiple => 'All tunnels by virtual router are ok' }, + { name => 'peer', type => 1, cb_prefix_output => 'prefix_peer_output', message_multiple => 'All tunnels by peer router are ok' }, + ]; + $self->{maps_counters}->{tunnel} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'state' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; + + $self->{maps_counters}->{vrtr} = [ + { label => 'vrtr-tunnel-total', set => { + key_values => [ { name => 'total_tunnel' }, { name => 'display' } ], + output_template => 'Total : %s', + perfdatas => [ + { label => 'vrtr_total_tunnel', value => 'total_tunnel_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'vrtr-tunnel-active-sessions', set => { + key_values => [ { name => 'active_sessions' }, { name => 'display' } ], + output_template => 'Active Sessions : %s', + perfdatas => [ + { label => 'vrtr_tunnel_active_sessions', value => 'active_sessions_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'vrtr-tunnel-total-sessions', set => { + key_values => [], + manual_keys => 1, + output_template => 'Total Sessions : %s', + threshold_use => 'total_sessions', output_use => 'total_sessions', + closure_custom_calc => $self->can('custom_total_sessions_calc'), + perfdatas => [ + { label => 'vrtr_tunnel_total_sessions', value => 'total_sessions', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; + + $self->{maps_counters}->{peer} = [ + { label => 'peer-tunnel-total', set => { + key_values => [ { name => 'total_tunnel' }, { name => 'display' } ], + output_template => 'Total : %s', + perfdatas => [ + { label => 'peer_total_tunnel', value => 'total_tunnel_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'peer-tunnel-active-sessions', set => { + key_values => [ { name => 'active_sessions' }, { name => 'display' } ], + output_template => 'Active Sessions : %s', + perfdatas => [ + { label => 'peer_tunnel_active_sessions', value => 'active_sessions_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'peer-tunnel-total-sessions', set => { + key_values => [], + manual_keys => 1, + output_template => 'Total Sessions : %s', + threshold_use => 'total_sessions', output_use => 'total_sessions', + closure_custom_calc => $self->can('custom_total_sessions_calc'), + perfdatas => [ + { label => 'peer_tunnel_total_sessions', value => 'total_sessions', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_tunnel_output { + my ($self, %options) = @_; + + return "Tunnel '" . $options{instance_value}->{display} . "' "; +} + +sub prefix_vrtr_output { + my ($self, %options) = @_; + + return "Virtual router '" . $options{instance_value}->{display} . "' Tunnel "; +} + +sub prefix_peer_output { + my ($self, %options) = @_; + + return "Peer '" . $options{instance_value}->{display} . "' Tunnel "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-vrtr-name:s" => { name => 'filter_vrtr_name' }, + "filter-peer-addr:s" => { name => 'filter_peer_addr' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +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_status = (1 => 'unknown', 2 => 'idle', 3 => 'waitReply', 4 => 'waitConn', + 5 => 'establishedIdle', 6 => 'established', 7 => 'draining', 8 => 'drained', + 9 => 'closed', 10 => 'closedByPeer' +); + +my $oid_vRtrName = '.1.3.6.1.4.1.6527.3.1.2.3.1.1.4'; +# index vRtrID and TuStatusId +my $mapping = { + tmnxL2tpTuStatusState => { oid => '.1.3.6.1.4.1.6527.3.1.2.60.1.3.2.2.1.2', map => \%map_status }, + tmnxL2tpTuStatusPeerAddr => { oid => '.1.3.6.1.4.1.6527.3.1.2.60.1.3.2.2.1.6' }, + tmnxL2tpTuStatsTotalSessions => { oid => '.1.3.6.1.4.1.6527.3.1.2.60.1.3.2.3.1.2' }, + tmnxL2tpTuStatsActiveSessions => { oid => '.1.3.6.1.4.1.6527.3.1.2.60.1.3.2.3.1.4' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_vRtrName }, + { oid => $mapping->{tmnxL2tpTuStatusPeerAddr}->{oid} }, + { oid => $mapping->{tmnxL2tpTuStatusState}->{oid} }, + ], return_type => 1, nothing_quit => 1); + $self->{vrtr} = {}; + $self->{peer} = {}; + $self->{tunnel} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{tmnxL2tpTuStatusState}->{oid}\.(.*?)\.(.*)$/); + my ($vrtr_id, $l2tp_tu_id) = ($1, $2); + + my $vrtr_name = $snmp_result->{$oid_vRtrName . '.' . $vrtr_id}; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $vrtr_id . '.' . $l2tp_tu_id); + my $peer_addr = inet_ntoa($result->{tmnxL2tpTuStatusPeerAddr}); + if (defined($self->{option_results}->{filter_vrtr_name}) && $self->{option_results}->{filter_vrtr_name} ne '' && + $vrtr_name !~ /$self->{option_results}->{filter_vrtr_name}/) { + $self->{output}->output_add(long_msg => "skipping vrtr '" . $vrtr_name . "'.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_peer_addr}) && $self->{option_results}->{filter_peer_addr} ne '' && + $peer_addr !~ /$self->{option_results}->{filter_peer_addr}/) { + $self->{output}->output_add(long_msg => "skipping peer addr '" . $peer_addr . "'.", debug => 1); + next; + } + + $self->{tunnel}->{$vrtr_id . '.' . $l2tp_tu_id} = { display => $vrtr_name . '-' . $peer_addr, state => $result->{tmnxL2tpTuStatusState} }; + $self->{vrtr}->{$vrtr_name} = { display => $vrtr_name, total_tunnel => 0, active_sessions => 0 } if (!defined($self->{vrtr}->{$vrtr_name})); + $self->{vrtr}->{$vrtr_name}->{total_tunnel}++; + + $self->{peer}->{$peer_addr} = { display => $peer_addr, total_tunnel => 0, active_sessions => 0 } if (!defined($self->{peer}->{$peer_addr})); + $self->{peer}->{$peer_addr}->{total_tunnel}++; + } + + $options{snmp}->load(oids => [$mapping->{tmnxL2tpTuStatsActiveSessions}->{oid}, $mapping->{tmnxL2tpTuStatsTotalSessions}->{oid}], + instances => [keys %{$self->{tunnel}}], instance_regexp => '^(.*)$'); + my $snmp_result2 = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{tunnel}}) { + /(\d+)\.\d+/; + my $vrtr_name = $snmp_result->{$oid_vRtrName . '.' . $1}; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => { %$snmp_result, %$snmp_result2 }, instance => $_); + my $peer_addr = inet_ntoa($result->{tmnxL2tpTuStatusPeerAddr}); + + $self->{vrtr}->{$vrtr_name}->{active_sessions} += $result->{tmnxL2tpTuStatsActiveSessions}; + $self->{peer}->{$peer_addr}->{active_sessions} += $result->{tmnxL2tpTuStatsActiveSessions}; + $self->{vrtr}->{$vrtr_name}->{'total_sessions_' . $_} = $result->{tmnxL2tpTuStatsTotalSessions}; + $self->{peer}->{$peer_addr}->{'total_sessions_' . $_} = $result->{tmnxL2tpTuStatsTotalSessions}; + } + + if (scalar(keys %{$self->{tunnel}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No tunnel found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "nokia_timos_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_vrtr_name}) ? md5_hex($self->{option_results}->{filter_vrtr_name}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_peer_addr}) ? md5_hex($self->{option_results}->{filter_peer_addr}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check L2TP usage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'vrtr-tunnel-total', 'vrtr-tunnel-active-sessions', 'vrtr-tunnel-total-sessions', +'peer-tunnel-total', 'peer-tunnel-active-sessions', 'peer-tunnel-total-sessions'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'vrtr-tunnel-total', 'vrtr-tunnel-active-sessions', 'vrtr-tunnel-total-sessions', +'peer-tunnel-total', 'peer-tunnel-active-sessions', 'peer-tunnel-total-sessions'. + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{display}, %{state} + +=item B<--critical-status> + +Set critical threshold for status. +Can used special variables like: %{display}, %{state} + +=item B<--filter-vrtr-name> + +Filter by vrtr name (can be a regexp). + +=item B<--filter-peer-addr> + +Filter by peer addr (can be a regexp). + +=back + +=cut diff --git a/network/nokia/timos/snmp/mode/listldp.pm b/network/nokia/timos/snmp/mode/listldp.pm index 58c510590..c0686433c 100644 --- a/network/nokia/timos/snmp/mode/listldp.pm +++ b/network/nokia/timos/snmp/mode/listldp.pm @@ -85,7 +85,7 @@ sub run { foreach my $instance (sort keys %{$self->{ldp}}) { $self->{output}->output_add(long_msg => '[name = ' . $self->{ldp}->{$instance}->{name} . "] [admin = '" . $self->{ldp}->{$instance}->{admin_state} . - "'][ipv4_oper = '" . $self->{ldp}->{$instance}->{ipv4_oper_state} . '"]'); + "'] [ipv4_oper = '" . $self->{ldp}->{$instance}->{ipv4_oper_state} . '"]'); } $self->{output}->output_add(severity => 'OK', diff --git a/network/nokia/timos/snmp/mode/listvrtr.pm b/network/nokia/timos/snmp/mode/listvrtr.pm new file mode 100644 index 000000000..bf48dd6fc --- /dev/null +++ b/network/nokia/timos/snmp/mode/listvrtr.pm @@ -0,0 +1,130 @@ +# +# Copyright 2017 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::nokia::timos::snmp::mode::listvrtr; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + }); + $self->{ldp} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my %map_type = (1 => 'baseRouter', 2 => 'vprn', 3 => 'vr'); +my $mapping = { + vRtrName => { oid => '.1.3.6.1.4.1.6527.3.1.2.3.1.1.4' }, + vRtrType => { oid => '.1.3.6.1.4.1.6527.3.1.2.3.1.1.28', map => \%map_type }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{vRtrName}->{oid} }, + { oid => $mapping->{vRtrType}->{oid} }, + ], + return_type => 1, nothing_quit => 1); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{vRtrName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{vRtrName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{vRtrName} . "': no matching filter.", debug => 1); + next; + } + + $self->{vrtr}->{$instance} = { + name => $result->{vRtrName}, + type => $result->{vRtrType} + }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{vrtr}}) { + $self->{output}->output_add(long_msg => '[name = ' . $self->{vrtr}->{$instance}->{name} . + "] [type = '" . $self->{vrtr}->{$instance}->{type} . + "']"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List virtual routers:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'type']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{vrtr}}) { + $self->{output}->add_disco_entry(name => $self->{vrtr}->{$instance}->{name}, + type => $self->{vrtr}->{$instance}->{type}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List virtual routers. + +=over 8 + +=item B<--filter-name> + +Filter by virtual router name (can be a regexp). + +=back + +=cut + diff --git a/network/nokia/timos/snmp/plugin.pm b/network/nokia/timos/snmp/plugin.pm index c86a13afc..675e88b70 100644 --- a/network/nokia/timos/snmp/plugin.pm +++ b/network/nokia/timos/snmp/plugin.pm @@ -33,10 +33,12 @@ sub new { %{$self->{modes}} = ( 'cpu' => 'network::nokia::timos::snmp::mode::cpu', 'hardware' => 'network::nokia::timos::snmp::mode::hardware', + 'l2tp-usage' => 'network::nokia::timos::snmp::mode::l2tpusage', 'ldp-usage' => 'network::nokia::timos::snmp::mode::ldpusage', 'interfaces' => 'snmp_standard::mode::interfaces', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', 'list-ldp' => 'network::nokia::timos::snmp::mode::listldp', + 'list-vrtr' => 'network::nokia::timos::snmp::mode::listvrtr', 'memory' => 'network::nokia::timos::snmp::mode::memory', 'uptime' => 'snmp_standard::mode::uptime', );