From c32f767f77f3d42fcaffa1e330c39ca0bff4c1c6 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 30 Mar 2021 11:18:19 +0200 Subject: [PATCH] add some modes (#2687) --- network/athonet/epc/snmp/mode/aggregate.pm | 134 ++++++++++++ network/athonet/epc/snmp/mode/apns.pm | 192 ++++++++++++++++++ .../epc/snmp/mode/interfacesdiameter.pm | 53 +++-- .../athonet/epc/snmp/mode/interfacesgtpc.pm | 39 +++- .../athonet/epc/snmp/mode/interfaceslte.pm | 3 +- network/athonet/epc/snmp/mode/license.pm | 174 +++++++++++----- network/athonet/epc/snmp/mode/listapns.pm | 111 ++++++++++ .../epc/snmp/mode/listinterfacesdiameter.pm | 11 +- .../epc/snmp/mode/listinterfacesgtpc.pm | 9 +- network/athonet/epc/snmp/plugin.pm | 3 + 10 files changed, 662 insertions(+), 67 deletions(-) create mode 100644 network/athonet/epc/snmp/mode/aggregate.pm create mode 100644 network/athonet/epc/snmp/mode/apns.pm create mode 100644 network/athonet/epc/snmp/mode/listapns.pm diff --git a/network/athonet/epc/snmp/mode/aggregate.pm b/network/athonet/epc/snmp/mode/aggregate.pm new file mode 100644 index 000000000..1291118f1 --- /dev/null +++ b/network/athonet/epc/snmp/mode/aggregate.pm @@ -0,0 +1,134 @@ +# +# Copyright 2021 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::athonet::epc::snmp::mode::aggregate; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'packets-in', nlabel => 'aggregate.packets.in.count', set => { + key_values => [ { name => 'packets_in', diff => 1 } ], + output_template => 'packets in: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'packets-out', nlabel => 'aggregate.packets.out.count', set => { + key_values => [ { name => 'packets_out', diff => 1 } ], + output_template => 'packets out: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'users-roaming-connected', nlabel => 'hss.users.roaming.connected.count', set => { + key_values => [ { name => 'roaming_users' } ], + output_template => 'roaming users connected: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'requests-authentication', nlabel => 'hss.requests.authentication.count', set => { + key_values => [ { name => 'auth_req', diff => 1 } ], + output_template => 'number of authentication requests: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'location-updates', nlabel => 'hss.location.updates.count', set => { + key_values => [ { name => 'location_updates', diff => 1 } ], + output_template => 'number of location updates: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + }); + + return $self; +} + +my $mapping = { + packets_in => { oid => '.1.3.6.1.4.1.35805.10.2.99.5' }, # loadPktInGi + packets_out => { oid => '.1.3.6.1.4.1.35805.10.2.99.6' }, # loadPktOutGi + roaming_users => { oid => '.1.3.6.1.4.1.35805.10.2.99.8' }, # hssRoamingUsers + auth_req => { oid => '.1.3.6.1.4.1.35805.10.2.99.9' }, # hssAuthenticationRequests + location_updates => { oid => '.1.3.6.1.4.1.35805.10.2.99.10' } # hssLocationUpdates +}; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cache_name} = 'athonet_epc_' . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + my $snmp_result = $options{snmp}->get_leef( + oids => [ map($_->{oid} . '.0', values(%$mapping)) ], + nothing_quit => 1 + ); + $self->{global} = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => 0); +} + +1; + +__END__ + +=head1 MODE + +Check aggregate statistics. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='roaming' + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'packets-in', 'packets-out', +'users-roaming-connected', 'requests-authentication', 'location-updates'. + +=back + +=cut diff --git a/network/athonet/epc/snmp/mode/apns.pm b/network/athonet/epc/snmp/mode/apns.pm new file mode 100644 index 000000000..584cf1618 --- /dev/null +++ b/network/athonet/epc/snmp/mode/apns.pm @@ -0,0 +1,192 @@ +# +# Copyright 2021 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::athonet::epc::snmp::mode::apns; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub prefix_apn_output { + my ($self, %options) = @_; + + return 'apn '; +} + +sub apn_long_output { + my ($self, %options) = @_; + + return sprintf( + "checking apn '%s'", + $options{instance_value}->{name} + );; +} + +sub prefix_traffic_output { + my ($self, %options) = @_; + + return 'traffic '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { + name => 'apns', type => 3, cb_prefix_output => 'prefix_apn_output', cb_long_output => 'apn_long_output', + indent_long_output => ' ', message_multiple => 'All access point names are ok', + group => [ + { name => 'traffic', type => 0, cb_prefix_output => 'prefix_traffic_output', skipped_code => { -10 => 1 } }, + { name => 'pdp', type => 0, skipped_code => { -10 => 1 } } + ] + } + ]; + + $self->{maps_counters}->{traffic} = [ + { label => 'traffic-in', nlabel => 'apn.traffic.in.bytespersecond', set => { + key_values => [ { name => 'traffic_in' } ], + output_template => 'in: %.2f %s/s', + output_change_bytes => 1, + perfdatas => [ + { template => '%.2f', unit => 'B/s', min => 0, label_extra_instance => 1 } + ] + } + }, + { label => 'traffic-out', nlabel => 'apn.traffic.out.bytespersecond', set => { + key_values => [ { name => 'traffic_out' } ], + output_template => 'out: %.2f %s/s', + output_change_bytes => 1, + perfdatas => [ + { template => '%.2f', unit => 'B/s', min => 0, label_extra_instance => 1 } + ] + } + } + ]; + + $self->{maps_counters}->{pdp} = [ + { label => 'pdp-contexts', nlabel => 'apn.pdp_contexts.count', set => { + key_values => [ { name => 'contexts', diff => 1 } ], + output_template => 'pdp contexts: %s', + perfdatas => [ + { template => '%s', min => 0, label_extra_instance => 1 } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' } + }); + + return $self; +} + +my $mapping = { + traffic_in => { oid => '.1.3.6.1.4.1.35805.10.2.99.14.1.2' }, # aPNRowDownlinkBytes + traffic_out => { oid => '.1.3.6.1.4.1.35805.10.2.99.14.1.3' }, # aPNRowUplinkBytes + pdp_contexts => { oid => '.1.3.6.1.4.1.35805.10.2.99.14.1.4' } # aPNRowPdpContexts +}; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cache_name} = 'athonet_epc_' . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + my $oid_apn_name = '.1.3.6.1.4.1.35805.10.2.99.14.1.1'; # aPNRowApnKey + my $snmp_result = $options{snmp}->get_table( + oid => $oid_apn_name, + nothing_quit => 1 + ); + + $self->{apns} = {}; + foreach (keys %$snmp_result) { + /^$oid_apn_name\.(.*)$/; + my $instance = $1; + my $name = $self->{output}->decode($snmp_result->{$_}); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{apns}->{$name} = { + instance => $instance, + name => $name, + traffic => {}, + context => {} + }; + } + + $self->{global}->{total} = scalar(keys %{$self->{apns}}); + return if (scalar(keys %{$self->{apns}}) <= 0); + + $options{snmp}->load(oids => [ + map($_->{oid}, values(%$mapping)) + ], + instances => [ map($_->{instance}, values(%{$self->{apns}})) ], + instance_regexp => '^(.*)$' + ); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{apns}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $self->{apns}->{$_}->{instance}); + $self->{apns}->{$_}->{traffic}->{traffic_in} = $result->{traffic_in}; + $self->{apns}->{$_}->{traffic}->{traffic_out} = $result->{traffic_out}; + $self->{apns}->{$_}->{pdp}->{contexts} = $result->{pdp_contexts}; + } +} + +1; + +__END__ + +=head1 MODE + +Check access point names. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='traffic' + +=item B<--filter-name> + +Filter APN by name (can be a regexp). + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'traffic-in', 'traffic-out', 'pdp-contexts'. + +=back + +=cut diff --git a/network/athonet/epc/snmp/mode/interfacesdiameter.pm b/network/athonet/epc/snmp/mode/interfacesdiameter.pm index c23f641e9..34e237c6c 100644 --- a/network/athonet/epc/snmp/mode/interfacesdiameter.pm +++ b/network/athonet/epc/snmp/mode/interfacesdiameter.pm @@ -49,10 +49,14 @@ sub prefix_interface_output { my ($self, %options) = @_; return sprintf( - "Diameter interface '%s' [local: %s] [peer: %s] ", + "Diameter interface '%s' [local: %s] [peer: %s]%s%s ", $options{instance_value}->{name}, $options{instance_value}->{local_hostname}, - $options{instance_value}->{peer_hostname} + $options{instance_value}->{peer_hostname}, + (defined($options{instance_value}->{secondary_local_addr}) && $options{instance_value}->{secondary_local_addr} ne '') ? + ' [secondary local: ' . $options{instance_value}->{secondary_local_addr} . ']' : '', + (defined($options{instance_value}->{secondary_peer_addr}) && $options{instance_value}->{secondary_peer_addr} ne '') ? + ' [secondary peer: ' . $options{instance_value}->{secondary_peer_addr} . ']' : '', ); } @@ -79,7 +83,9 @@ sub set_counters { { label => 'status', type => 2, critical_default => '%{status} =~ /down/i', set => { - key_values => [ { name => 'status' }, { name => 'name' } ], + key_values => [ + { name => 'status' }, { name => 'name' }, { name => 'owner' } + ], closure_custom_output => $self->can('custom_status_output'), closure_custom_perfdata => sub { return 0; }, closure_custom_threshold_check => \&catalog_status_threshold_ng @@ -103,7 +109,8 @@ sub new { bless $self, $class; $options{options}->add_options(arguments => { - 'filter-name:s' => { name => 'filter_name' } + 'filter-name:s' => { name => 'filter_name' }, + 'filter-owner:s' => { name => 'filter_owner' } }); return $self; @@ -111,12 +118,21 @@ sub new { my $map_status = { 0 => 'down', 1 => 'up' }; my $map_transport_type = { 0 => 'sctp', 1 => 'tcp', 2 => 'udp' }; +my $map_owner = { + 0 => 'unknown', 1 => 'mme', 2 => 'msc', 3 => 'sgsn', + 4 => 'fgw', 5 => 'wifi', 6 => 'spgw', 7 => 'hlr-hss', + 8 => 'sgw', 9 => 'pgw', 10 => 'pcrf', 11 => 'dpiaf', + 12 => 'aaa', 13 => 'ocs' +}; my $mapping = { - peer_hostname => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.4' }, # iDiameterPeerHostName - transport_type => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.8', map => $map_transport_type }, # iDiameterTransportType - transport_status => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.9', map => $map_status }, # iDiameterTransportState - status => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.10', map => $map_status } # iDiameterState + peer_hostname => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.4' }, # iDiameterPeerHostName + transport_type => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.8', map => $map_transport_type }, # iDiameterTransportType + transport_status => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.9', map => $map_status }, # iDiameterTransportState + status => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.10', map => $map_status }, # iDiameterState + owner => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.11', map => $map_owner }, # iDiameterOwner + secondary_local_addr => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.12' }, # iDiameterSecondaryLocalAddress + secondary_peer_addr => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.13' } # iDiameterSecondaryPeerAddress }; sub manage_selection { @@ -146,7 +162,7 @@ sub manage_selection { }; } - $self->{global} = { total => scalar(keys %{$self->{interfaces}}) }; + $self->{global} = { total => 0 }; return if (scalar(keys %{$self->{interfaces}}) <= 0); @@ -161,8 +177,17 @@ sub manage_selection { foreach (keys %{$self->{interfaces}}) { my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + if (defined($self->{option_results}->{filter_owner}) && $self->{option_results}->{filter_owner} ne '' && + $result->{owner} !~ /$self->{option_results}->{filter_owner}/) { + $self->{output}->output_add(long_msg => "skipping '" . $self->{interfaces}->{$_}->{name} . "': no matching filter.", debug => 1); + delete $self->{interfaces}->{$_}; + next; + } + $self->{interfaces}->{$_} = { %{$self->{interfaces}->{$_}}, %$result }; } + + $self->{global}->{total} = scalar(keys %{$self->{interfaces}}); } 1; @@ -184,20 +209,24 @@ Example: --filter-counters='transport' Filter interfaces by name (can be a regexp). +=item B<--filter-owner> + +Filter interfaces by owner (can be a regexp). + =item B<--unknown-status> Set unknown threshold for status. -Can used special variables like: %{status}, %{name} +Can used special variables like: %{status}, %{name}, %{owner} =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{status}, %{name} +Can used special variables like: %{status}, %{name}, %{owner} =item B<--critical-status> Set critical threshold for status (Default: '%{status} =~ /down/i'). -Can used special variables like: %{status}, %{name} +Can used special variables like: %{status}, %{name}, %{owner} =item B<--unknown-transport-status> diff --git a/network/athonet/epc/snmp/mode/interfacesgtpc.pm b/network/athonet/epc/snmp/mode/interfacesgtpc.pm index 0a895f1bb..3f35b2b2e 100644 --- a/network/athonet/epc/snmp/mode/interfacesgtpc.pm +++ b/network/athonet/epc/snmp/mode/interfacesgtpc.pm @@ -39,10 +39,11 @@ sub prefix_interface_output { my ($self, %options) = @_; return sprintf( - "Gtp control interface source '%s' destination '%s' [type: %s] ", + "Gtp control interface source '%s' destination '%s' [type: %s] [owner: %s] ", $options{instance_value}->{source_address}, $options{instance_value}->{destination_address}, - $options{instance_value}->{type} + $options{instance_value}->{type}, + $options{instance_value}->{owner} ); } @@ -85,7 +86,8 @@ sub new { $options{options}->add_options(arguments => { 'filter-source-address:s' => { name => 'filter_source_address' }, - 'filter-destination-address:s' => { name => 'filter_destination_address' } + 'filter-destination-address:s' => { name => 'filter_destination_address' }, + 'filter-type:s' => { name => 'filter_type' } }); return $self; @@ -93,6 +95,14 @@ sub new { my $map_status = { 0 => 'down', 1 => 'up' }; my $map_type = { 1 => 'gTPv1', 2 => 'gTPv2', 11 => 'gTPPrime' }; +my $map_owner = { + 0 => 'unknown', 1 => 'mme', 2 => 'msc', 3 => 'sgsn', + 4 => 'fgw', 5 => 'wifi', 6 => 'sgw', 7 => 'pgw', 8 => 'hlr-hss' +}; + +my $mapping = { + owner => { oid => '.1.3.6.1.4.1.35805.10.2.12.9.1.8', map => $map_owner } # gTPcOwner +}; sub manage_selection { my ($self, %options) = @_; @@ -123,6 +133,11 @@ sub manage_selection { $self->{output}->output_add(long_msg => "skipping '" . $destination_address . "': no matching filter.", debug => 1); next; } + if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && + $type !~ /$self->{option_results}->{filter_type}/) { + $self->{output}->output_add(long_msg => "skipping '" . $type . "': no matching filter.", debug => 1); + next; + } $self->{interfaces}->{$instance} = { source_address => $source_address, @@ -133,6 +148,20 @@ sub manage_selection { } $self->{global} = { total => scalar(keys %{$self->{interfaces}}) }; + return if (scalar(keys %{$self->{interfaces}}) <= 0); + + $options{snmp}->load(oids => [ + map($_->{oid}, values(%$mapping)) + ], + instances => [keys %{$self->{interfaces}}], + instance_regexp => '^(.*)$' + ); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{interfaces}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + $self->{interfaces}->{$_} = { %{$self->{interfaces}->{$_}}, %$result }; + } } 1; @@ -153,6 +182,10 @@ Filter interfaces by source address (can be a regexp). Filter interfaces by destination address (can be a regexp). +=item B<--filter-type> + +Filter interfaces by type (can be a regexp). + =item B<--unknown-status> Set unknown threshold for status. diff --git a/network/athonet/epc/snmp/mode/interfaceslte.pm b/network/athonet/epc/snmp/mode/interfaceslte.pm index 2c8341de2..3da0c22bb 100644 --- a/network/athonet/epc/snmp/mode/interfaceslte.pm +++ b/network/athonet/epc/snmp/mode/interfaceslte.pm @@ -96,7 +96,8 @@ sub prefix_interface_output { sub interface_long_output { my ($self, %options) = @_; - return sprintf("checking lte interface '%s' [eNodeB ID: %s]", + return sprintf( + "checking lte interface '%s' [eNodeB ID: %s]", $options{instance_value}->{name}, $options{instance_value}->{enbid} ); diff --git a/network/athonet/epc/snmp/mode/license.pm b/network/athonet/epc/snmp/mode/license.pm index ac12e3a6d..5c6fb64c1 100644 --- a/network/athonet/epc/snmp/mode/license.pm +++ b/network/athonet/epc/snmp/mode/license.pm @@ -39,11 +39,11 @@ sub custom_license_users_output { return sprintf( 'active users total: %s used: %s (%.2f%%) free: %s (%.2f%%)', - $self->{result_values}->{users_total}, - $self->{result_values}->{users_used}, - $self->{result_values}->{users_prct_used}, - $self->{result_values}->{users_free}, - $self->{result_values}->{users_prct_free} + $self->{result_values}->{total}, + $self->{result_values}->{used}, + $self->{result_values}->{prct_used}, + $self->{result_values}->{free}, + $self->{result_values}->{prct_free} ); } @@ -52,28 +52,54 @@ sub custom_license_sessions_output { return sprintf( 'active sessions total: %s used: %s (%.2f%%) free: %s (%.2f%%)', - $self->{result_values}->{sessions_total}, - $self->{result_values}->{sessions_used}, - $self->{result_values}->{sessions_prct_used}, - $self->{result_values}->{sessions_free}, - $self->{result_values}->{sessions_prct_free} + $self->{result_values}->{total}, + $self->{result_values}->{used}, + $self->{result_values}->{prct_used}, + $self->{result_values}->{free}, + $self->{result_values}->{prct_free} ); } -sub prefix_global_output { +sub custom_license_usim_output { my ($self, %options) = @_; - return 'License '; + return sprintf( + 'provisioned usim total: %s used: %s (%.2f%%) free: %s (%.2f%%)', + $self->{result_values}->{total}, + $self->{result_values}->{used}, + $self->{result_values}->{prct_used}, + $self->{result_values}->{free}, + $self->{result_values}->{prct_free} + ); +} + +sub license_long_output { + my ($self, %options) = @_; + + return 'checking license'; +} + +sub prefix_license_output { + my ($self, %options) = @_; + + return 'license '; } sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' } + { name => 'license', type => 3, cb_long_output => 'license_long_output', indent_long_output => ' ', + group => [ + { name => 'expire', type => 0, display_short => 0, cb_prefix_output => 'prefix_license_output', skipped_code => { -10 => 1 } }, + { name => 'users', type => 0, display_short => 0, skipped_code => { -10 => 1 } }, + { name => 'sessions', type => 0, display_short => 0, skipped_code => { -10 => 1 } }, + { name => 'usim', type => 0, display_short => 0, skipped_code => { -10 => 1 } } + ] + } ]; - $self->{maps_counters}->{global} = [ + $self->{maps_counters}->{expire} = [ { label => 'status', type => 2, @@ -93,55 +119,88 @@ sub set_counters { { template => '%d', min => 0, unit => 's' } ] } - }, + } + ]; + + $self->{maps_counters}->{users} = [ { label => 'license-users-usage', nlabel => 'license.users.active.usage.count', set => { - key_values => [ { name => 'users_used' }, { name => 'users_free' }, { name => 'users_prct_used' }, { name => 'users_prct_free' }, { name => 'users_total' } ], + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], closure_custom_output => $self->can('custom_license_users_output'), perfdatas => [ - { template => '%d', min => 0, max => 'users_total' } + { template => '%d', min => 0, max => 'total' } ] } }, { label => 'license-users-free', display_ok => 0, nlabel => 'license.users.active.free.count', set => { - key_values => [ { name => 'users_free' }, { name => 'users_used' }, { name => 'users_prct_used' }, { name => 'users_prct_free' }, { name => 'users_total' } ], + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], closure_custom_output => $self->can('custom_license_users_output'), perfdatas => [ - { template => '%d', min => 0, max => 'users_total' } + { template => '%d', min => 0, max => 'total' } ] } }, { label => 'license-users-usage-prct', display_ok => 0, nlabel => 'license.users.active.usage.percentage', set => { - key_values => [ { name => 'users_prct_used' }, { name => 'users_free' }, { name => 'users_used' }, { name => 'users_prct_free' }, { name => 'users_total' } ], + key_values => [ { name => 'prct_used' }, { name => 'used' }, { name => 'free' }, { name => 'prct_free' }, { name => 'total' } ], closure_custom_output => $self->can('custom_license_users_output'), perfdatas => [ { template => '%.2f', min => 0, max => 100, unit => '%' } ] } - }, + } + ]; + + $self->{maps_counters}->{sessions} = [ { label => 'license-sessions-usage', nlabel => 'license.sessions.active.usage.count', set => { - key_values => [ { name => 'sessions_used' }, { name => 'sessions_free' }, { name => 'sessions_prct_used' }, { name => 'sessions_prct_free' }, { name => 'sessions_total' } ], + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], closure_custom_output => $self->can('custom_license_sessions_output'), perfdatas => [ - { template => '%d', min => 0, max => 'sessions_total' } + { template => '%d', min => 0, max => 'total' } ] } }, { label => 'license-sessions-free', display_ok => 0, nlabel => 'license.sessions.active.free.count', set => { - key_values => [ { name => 'sessions_free' }, { name => 'sessions_used' }, { name => 'sessions_prct_used' }, { name => 'sessions_prct_free' }, { name => 'sessions_total' } ], + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], closure_custom_output => $self->can('custom_license_sessions_output'), perfdatas => [ - { template => '%d', min => 0, max => 'sessions_total' } + { template => '%d', min => 0, max => 'total' } ] } }, { label => 'license-sessions-usage-prct', display_ok => 0, nlabel => 'license.sessions.active.usage.percentage', set => { - key_values => [ { name => 'sessions_prct_used' }, { name => 'sessions_used' }, { name => 'sessions_free' }, { name => 'sessions_prct_free' }, { name => 'sessions_total' } ], + key_values => [ { name => 'prct_used' }, { name => 'used' }, { name => 'free' }, { name => 'prct_free' }, { name => 'total' } ], closure_custom_output => $self->can('custom_license_sessions_output'), perfdatas => [ { template => '%.2f', min => 0, max => 100, unit => '%' } ] } + } + ]; + + $self->{maps_counters}->{usim} = [ + { label => 'license-usim-usage', nlabel => 'license.usim.usage.count', set => { + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_license_usim_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total' } + ] + } }, + { label => 'license-usim-free', display_ok => 0, nlabel => 'license.usim.free.count', set => { + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_license_usim_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total' } + ] + } + }, + { label => 'license-usim-usage-prct', display_ok => 0, nlabel => 'license.usim.usage.percentage', set => { + key_values => [ { name => 'prct_used' }, { name => 'used' }, { name => 'free' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_license_usim_output'), + perfdatas => [ + { template => '%.2f', min => 0, max => 100, unit => '%' } + ] + } + } ]; } @@ -159,12 +218,14 @@ sub new { my $map_status = { 0 => 'ok', 1 => 'expired', 2 => 'invalid' }; my $mapping = { - users_connected => { oid => '.1.3.6.1.4.1.35805.10.2.99.1' }, # usersConnected - active_connections => { oid => '.1.3.6.1.4.1.35805.10.2.99.4' }, # activeConnections - max_active_users => { oid => '.1.3.6.1.4.1.35805.10.4.1' }, # maxActiveUsers - max_active_sessions => { oid => '.1.3.6.1.4.1.35805.10.4.2' }, # maxActiveSessions - expire_time => { oid => '.1.3.6.1.4.1.35805.10.4.4' }, # licenseExpireTime - status => { oid => '.1.3.6.1.4.1.35805.10.4.5', map => $map_status } # licenseStatus + users_connected => { oid => '.1.3.6.1.4.1.35805.10.2.99.1' }, # usersConnected + active_connections => { oid => '.1.3.6.1.4.1.35805.10.2.99.4' }, # activeConnections + hss_provisioned_users => { oid => '.1.3.6.1.4.1.35805.10.2.99.7' }, # hssProvisionedUsers + max_active_users => { oid => '.1.3.6.1.4.1.35805.10.4.1' }, # maxActiveUsers + max_active_sessions => { oid => '.1.3.6.1.4.1.35805.10.4.2' }, # maxActiveSessions + expire_time => { oid => '.1.3.6.1.4.1.35805.10.4.4' }, # licenseExpireTime + max_provisioned_usim => { oid => '.1.3.6.1.4.1.35805.10.4.6' }, # maxProvisionedUSIM + status => { oid => '.1.3.6.1.4.1.35805.10.4.5', map => $map_status } # licenseStatus }; sub manage_selection { @@ -174,10 +235,20 @@ sub manage_selection { oids => [ map($_->{oid} . '.0', values(%$mapping)) ], nothing_quit => 1 ); - $self->{global} = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => 0); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => 0); + $self->{output}->output_add(short_msg => 'License is ok'); + + $self->{license} = { + global => { + expire => { status => $result->{status} }, + users => {}, + sessions => {}, + usim => {} + } + }; #2035-3-30,7:43:58.0,+0:0 - if ($self->{global}->{expire_time} =~ /^\s*(\d+)-(\d+)-(\d+),(\d+):(\d+):(\d+)\.(\d+),(.*)/) { + if ($result->{expire_time} =~ /^\s*(\d+)-(\d+)-(\d+),(\d+):(\d+):(\d+)\.(\d+),(.*)/) { my $dt = DateTime->new( year => $1, month => $2, @@ -187,21 +258,29 @@ sub manage_selection { second => $6, time_zone => $7 ); - $self->{global}->{expires_seconds} = $dt->epoch() - time(); - $self->{global}->{expires_human} = centreon::plugins::misc::change_seconds(value => $self->{global}->{expires_seconds}); + $self->{license}->{global}->{expire}->{expires_seconds} = $dt->epoch() - time(); + $self->{license}->{global}->{expire}->{expires_human} = centreon::plugins::misc::change_seconds( + value => $self->{license}->{global}->{expire}->{expires_seconds} + ); } - $self->{global}->{users_used} = $self->{global}->{users_connected}; - $self->{global}->{users_total} = $self->{global}->{max_active_users}; - $self->{global}->{users_free} = $self->{global}->{users_total} - $self->{global}->{users_used}; - $self->{global}->{users_prct_used} = $self->{global}->{users_used} * 100 / $self->{global}->{users_total}; - $self->{global}->{users_prct_free} = 100 - $self->{global}->{users_prct_used}; + $self->{license}->{global}->{users}->{used} = $result->{users_connected}; + $self->{license}->{global}->{users}->{total} = $result->{max_active_users}; + $self->{license}->{global}->{users}->{free} = $result->{max_active_users} - $result->{users_connected}; + $self->{license}->{global}->{users}->{prct_used} = $result->{users_connected} * 100 / $result->{max_active_users}; + $self->{license}->{global}->{users}->{prct_free} = 100 - $self->{license}->{global}->{users}->{prct_used}; - $self->{global}->{sessions_used} = $self->{global}->{active_connections}; - $self->{global}->{sessions_total} = $self->{global}->{max_active_sessions}; - $self->{global}->{sessions_free} = $self->{global}->{sessions_total} - $self->{global}->{sessions_used}; - $self->{global}->{sessions_prct_used} = $self->{global}->{sessions_used} * 100 / $self->{global}->{sessions_total}; - $self->{global}->{sessions_prct_free} = 100 - $self->{global}->{sessions_prct_used}; + $self->{license}->{global}->{sessions}->{used} = $result->{active_connections}; + $self->{license}->{global}->{sessions}->{total} = $result->{max_active_sessions}; + $self->{license}->{global}->{sessions}->{free} = $result->{max_active_sessions} - $result->{active_connections}; + $self->{license}->{global}->{sessions}->{prct_used} = $result->{active_connections} * 100 / $result->{max_active_sessions}; + $self->{license}->{global}->{sessions}->{prct_free} = 100 - $self->{license}->{global}->{sessions}->{prct_used}; + + $self->{license}->{global}->{usim}->{used} = $result->{hss_provisioned_users}; + $self->{license}->{global}->{usim}->{total} = $result->{max_provisioned_usim}; + $self->{license}->{global}->{usim}->{free} = $result->{max_provisioned_usim} - $result->{hss_provisioned_users}; + $self->{license}->{global}->{usim}->{prct_used} = $result->{hss_provisioned_users} * 100 / $result->{max_provisioned_usim}; + $self->{license}->{global}->{usim}->{prct_free} = 100 - $self->{license}->{global}->{users}->{prct_used}; } 1; @@ -233,7 +312,8 @@ Can use special variables like: %{status} Thresholds. Can be: 'expires-seconds', 'license-users-usage', 'license-users-free', 'license-users-usage-prct', -'license-sessions-usage', 'license-sessions-free', 'license-sessions-usage-prct'. +'license-sessions-usage', 'license-sessions-free', 'license-sessions-usage-prct', +'license-usim-usage', 'license-usim-free', 'license-usim-usage-prct'. =back diff --git a/network/athonet/epc/snmp/mode/listapns.pm b/network/athonet/epc/snmp/mode/listapns.pm new file mode 100644 index 000000000..7e72e2ea7 --- /dev/null +++ b/network/athonet/epc/snmp/mode/listapns.pm @@ -0,0 +1,111 @@ +# +# Copyright 2021 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::athonet::epc::snmp::mode::listapns; + +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; + + $options{options}->add_options(arguments => { + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my $mapping = { + name => { oid => '.1.3.6.1.4.1.35805.10.2.99.14.1.1' } # aPNRowApnKey +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table( + oid => $mapping->{name}->{oid}, + nothing_quit => 1 + ); + + my $results = {}; + foreach (keys %$snmp_result) { + my $name = $self->{output}->decode($snmp_result->{$_}); + $results->{$name} = { name => $name }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(snmp => $options{snmp}); + foreach my $name (sort keys %$results) { + $self->{output}->output_add(long_msg => + join('', map("[$_ = " . $results->{$name}->{$_} . ']', keys(%$mapping))) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List access point names:' + ); + $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 => [keys %$mapping]); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(snmp => $options{snmp}); + foreach (sort keys %$results) { + $self->{output}->add_disco_entry( + %{$results->{$_}} + ); + } +} + +1; + +__END__ + +=head1 MODE + +List access point names. + +=over 8 + +=back + +=cut diff --git a/network/athonet/epc/snmp/mode/listinterfacesdiameter.pm b/network/athonet/epc/snmp/mode/listinterfacesdiameter.pm index 0ee7feef4..88d5402c5 100644 --- a/network/athonet/epc/snmp/mode/listinterfacesdiameter.pm +++ b/network/athonet/epc/snmp/mode/listinterfacesdiameter.pm @@ -42,6 +42,12 @@ sub check_options { my $map_status = { 0 => 'down', 1 => 'up' }; my $map_transport_type = { 0 => 'sctp', 1 => 'tcp', 2 => 'udp' }; +my $map_owner = { + 0 => 'unknown', 1 => 'mme', 2 => 'msc', 3 => 'sgsn', + 4 => 'fgw', 5 => 'wifi', 6 => 'spgw', 7 => 'hlr-hss', + 8 => 'sgw', 9 => 'pgw', 10 => 'pcrf', 11 => 'dpiaf', + 12 => 'aaa', 13 => 'ocs' +}; my $mapping = { local_hostname => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.2' }, # iDiameterLocalHostName @@ -52,7 +58,8 @@ my $mapping = { peer_address => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.7' }, # iDiameterPeerAddress transport_type => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.8', map => $map_transport_type }, # iDiameterTransportType transport_status => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.9', map => $map_status }, # iDiameterTransportState - status => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.10', map => $map_status } # iDiameterState + status => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.10', map => $map_status }, # iDiameterState + owner => { oid => '.1.3.6.1.4.1.35805.10.2.12.2.1.11', map => $map_owner } # iDiameterOwner }; my $oid_diameterInterfacesEntry = '.1.3.6.1.4.1.35805.10.2.12.2.1'; @@ -62,7 +69,7 @@ sub manage_selection { my $snmp_result = $options{snmp}->get_table( oid => $oid_diameterInterfacesEntry, start => $mapping->{local_hostname}->{oid}, - end => $mapping->{status}->{oid}, + end => $mapping->{owner}->{oid}, nothing_quit => 1 ); diff --git a/network/athonet/epc/snmp/mode/listinterfacesgtpc.pm b/network/athonet/epc/snmp/mode/listinterfacesgtpc.pm index 780b76fb9..535794141 100644 --- a/network/athonet/epc/snmp/mode/listinterfacesgtpc.pm +++ b/network/athonet/epc/snmp/mode/listinterfacesgtpc.pm @@ -42,12 +42,17 @@ sub check_options { my $map_status = { 0 => 'down', 1 => 'up' }; my $map_type = { 1 => 'gTPv1', 2 => 'gTPv2', 11 => 'gTPPrime' }; +my $map_owner = { + 0 => 'unknown', 1 => 'mme', 2 => 'msc', 3 => 'sgsn', + 4 => 'fgw', 5 => 'wifi', 6 => 'sgw', 7 => 'pgw', 8 => 'hlr-hss' +}; my $mapping = { source_address => { oid => '.1.3.6.1.4.1.35805.10.2.12.9.1.1' }, # gTPcAddressSource destination_address => { oid => '.1.3.6.1.4.1.35805.10.2.12.9.1.3' }, # gTPcAddressDestination type => { oid => '.1.3.6.1.4.1.35805.10.2.12.9.1.5', map => $map_type }, # gTPcGTPType - status => { oid => '.1.3.6.1.4.1.35805.10.2.12.9.1.6', map => $map_status } # gTPcState + status => { oid => '.1.3.6.1.4.1.35805.10.2.12.9.1.6', map => $map_status }, # gTPcState + owner => { oid => '.1.3.6.1.4.1.35805.10.2.12.9.1.8', map => $map_owner } # gTPcOwner }; my $oid_gtpcInterfacesEntry = '.1.3.6.1.4.1.35805.10.2.12.9.1'; @@ -56,7 +61,7 @@ sub manage_selection { my $snmp_result = $options{snmp}->get_table( oid => $oid_gtpcInterfacesEntry, - end => $mapping->{status}->{oid}, + end => $mapping->{owner}->{oid}, nothing_quit => 1 ); diff --git a/network/athonet/epc/snmp/plugin.pm b/network/athonet/epc/snmp/plugin.pm index c1225df8b..ea5f6d5a5 100644 --- a/network/athonet/epc/snmp/plugin.pm +++ b/network/athonet/epc/snmp/plugin.pm @@ -31,11 +31,14 @@ sub new { $self->{version} = '1.0'; $self->{modes} = { + 'aggregate' => 'network::athonet::epc::snmp::mode::aggregate', + 'apns' => 'network::athonet::epc::snmp::mode::apns', 'interfaces-diameter' => 'network::athonet::epc::snmp::mode::interfacesdiameter', 'interfaces-lte' => 'network::athonet::epc::snmp::mode::interfaceslte', 'interfaces-ga' => 'network::athonet::epc::snmp::mode::interfacesga', 'interfaces-gtpc' => 'network::athonet::epc::snmp::mode::interfacesgtpc', 'license' => 'network::athonet::epc::snmp::mode::license', + 'list-apns' => 'network::athonet::epc::snmp::mode::listapns', 'list-interfaces-diameter' => 'network::athonet::epc::snmp::mode::listinterfacesdiameter', 'list-interfaces-ga' => 'network::athonet::epc::snmp::mode::listinterfacesga', 'list-interfaces-gtpc' => 'network::athonet::epc::snmp::mode::listinterfacesgtpc',