From 81d2189d2edef7ef706fc9a2895332a28abe5146 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 22 Dec 2017 14:07:08 +0100 Subject: [PATCH] add cisco call manager plugin snmp --- .../cisco/callmanager/snmp/mode/ccmusage.pm | 234 ++++++++++++++++++ .../callmanager/snmp/mode/gatewayusage.pm | 223 +++++++++++++++++ .../callmanager/snmp/mode/mediadeviceusage.pm | 223 +++++++++++++++++ .../cisco/callmanager/snmp/mode/phoneusage.pm | 223 +++++++++++++++++ network/cisco/callmanager/snmp/plugin.pm | 51 ++++ 5 files changed, 954 insertions(+) create mode 100644 network/cisco/callmanager/snmp/mode/ccmusage.pm create mode 100644 network/cisco/callmanager/snmp/mode/gatewayusage.pm create mode 100644 network/cisco/callmanager/snmp/mode/mediadeviceusage.pm create mode 100644 network/cisco/callmanager/snmp/mode/phoneusage.pm create mode 100644 network/cisco/callmanager/snmp/plugin.pm diff --git a/network/cisco/callmanager/snmp/mode/ccmusage.pm b/network/cisco/callmanager/snmp/mode/ccmusage.pm new file mode 100644 index 000000000..99fadb87b --- /dev/null +++ b/network/cisco/callmanager/snmp/mode/ccmusage.pm @@ -0,0 +1,234 @@ +# +# 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::cisco::callmanager::snmp::mode::ccmusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +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 = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_ccmStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_ccmName'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'ccm', type => 1, cb_prefix_output => 'prefix_ccm_output', message_multiple => 'All CCM are ok' }, + ]; + + $self->{maps_counters}->{ccm} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'ccmStatus' }, { name => 'ccmName' } ], + 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'), + } + }, + ]; + + my @map = ( + ['phones-registered', 'Phones Registered : %s', 'ccmRegisteredPhones'], + ['phones-unregistered', 'Phones Unregistered : %s', 'ccmUnregisteredPhones'], + ['phones-rejected', 'Phones Rejected : %s', 'ccmRejectedPhones'], + ['gateways-registered', 'Gateways Registered : %s', 'ccmRegisteredPhones'], + ['gateways-unregistered', 'Gateways Unregistered : %s', 'ccmUnregisteredGateways'], + ['gateways-rejected', 'Gateways Rejected : %s', 'ccmRejectedGateways'], + ['mediadevices-registered', 'Media Devices Registered : %s', 'ccmRegisteredMediaDevices'], + ['mediadevices-unregistered', 'Media Devices Unregistered : %s', 'ccmUnregisteredMediaDevices'], + ['mediadevices-rejected', 'Media Devices Rejected : %s', 'ccmRejectedMediaDevices'], + ); + + $self->{maps_counters}->{global} = []; + foreach (@map) { + my $label = $_->[0]; + $label =~ tr/-/_/; + push @{$self->{maps_counters}->{global}}, { label => $_->[0], set => { + key_values => [ { name => $_->[2] } ], + output_template => $_->[1], + perfdatas => [ + { label => $label, value => $_->[2] . '_absolute', template => '%s', min => 0 }, + ], + } + }, + } +} + +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 => + { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /up/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_ccm_output { + my ($self, %options) = @_; + + return "CCM '" . $options{instance_value}->{ccmName} . "' "; +} + +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 %mapping_status = (1 => 'unknown', 2 => 'up', 3 => 'down'); + +my $mapping = { + ccmRegisteredPhones => { oid => '.1.3.6.1.4.1.9.9.156.1.5.5' }, + ccmUnregisteredPhones => { oid => '.1.3.6.1.4.1.9.9.156.1.5.6' }, + ccmRejectedPhones => { oid => '.1.3.6.1.4.1.9.9.156.1.5.7' }, + ccmRegisteredGateways => { oid => '.1.3.6.1.4.1.9.9.156.1.5.8' }, + ccmUnregisteredGateways => { oid => '.1.3.6.1.4.1.9.9.156.1.5.9' }, + ccmRejectedGateways => { oid => '.1.3.6.1.4.1.9.9.156.1.5.10' }, + ccmRegisteredMediaDevices => { oid => '.1.3.6.1.4.1.9.9.156.1.5.11' }, + ccmUnregisteredMediaDevices => { oid => '.1.3.6.1.4.1.9.9.156.1.5.12' }, + ccmRejectedMediaDevices => { oid => '.1.3.6.1.4.1.9.9.156.1.5.13' }, +}; +my $mapping2 = { + ccmName => { oid => '.1.3.6.1.4.1.9.9.156.1.1.2.1.2' }, + ccmStatus => { oid => '.1.3.6.1.4.1.9.9.156.1.1.2.1.5', map => \%mapping_status }, +}; + +my $oid_ccmGlobalInfo = '.1.3.6.1.4.1.9.9.156.1.5'; +my $oid_ccmEntry = '.1.3.6.1.4.1.9.9.156.1.1.2.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_ccmGlobalInfo, end => $mapping->{ccmRejectedMediaDevices}->{oid} }, + { oid => $oid_ccmEntry, end => $mapping2->{ccmStatus}->{oid} }, + ], nothing_quit => 1); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result->{$oid_ccmGlobalInfo}, instance => '0'); + $self->{global} = { %$result }; + + $self->{ccm} = {}; + foreach my $oid (keys %{$snmp_result->{$oid_ccmEntry}}) { + next if ($oid !~ /^$mapping2->{ccmStatus}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result->{$oid_ccmEntry}, instance => $instance); + + $self->{ccm}->{$instance} = { %$result }; + } +} + +1; + +__END__ + +=head1 MODE + +Check cisco call manager global usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='phone' + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /up/'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. + +=item B<--critical-*> + +Threshold critical. + +Can be: 'phones-registered', 'phones-unregistered', 'phones-rejected', +'gateways-registered', 'gateways-unregistered', 'gateways-rejected', +'mediadevices-registered', 'mediadevices-unregistered', 'mediadevices-rejected'. + +=back + +=cut diff --git a/network/cisco/callmanager/snmp/mode/gatewayusage.pm b/network/cisco/callmanager/snmp/mode/gatewayusage.pm new file mode 100644 index 000000000..57bf999a3 --- /dev/null +++ b/network/cisco/callmanager/snmp/mode/gatewayusage.pm @@ -0,0 +1,223 @@ +# +# 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::cisco::callmanager::snmp::mode::gatewayusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +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 = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_ccmGatewayStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_ccmGatewayName'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'gateway', type => 1, cb_prefix_output => 'prefix_gateway_output', message_multiple => 'All gateways are ok' }, + ]; + + $self->{maps_counters}->{gateway} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'ccmGatewayStatus' }, { name => 'ccmGatewayName' } ], + 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'), + } + }, + ]; + + my @map = ( + ['total-registered', 'Registered : %s', 'registered'], + ['total-unregistered', 'Unregistered : %s', 'unregistered'], + ['total-rejected', 'Rejected : %s', 'rejected'], + ['total-unknown', 'Unknown : %s', 'unknown'], + ['total-partiallyregistered', 'Partially Registered : %s', 'partiallyregistered'], + ); + + $self->{maps_counters}->{global} = []; + foreach (@map) { + my $label = $_->[0]; + $label =~ tr/-/_/; + push @{$self->{maps_counters}->{global}}, { label => $_->[0], set => { + key_values => [ { name => $_->[2] } ], + output_template => $_->[1], + perfdatas => [ + { label => $label, value => $_->[2] . '_absolute', template => '%s', min => 0 }, + ], + } + }, + } +} + +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 => + { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /^registered/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_gateway_output { + my ($self, %options) = @_; + + return "Gateway '" . $options{instance_value}->{ccmGatewayName} . "' "; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Total "; +} + +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 %mapping_status = ( + 1 => 'unknown', 2 => 'registered', 3 => 'unregistered', + 4 => 'rejected', 5 => 'partiallyregistered', +); + +my $mapping = { + ccmGatewayName => { oid => '.1.3.6.1.4.1.9.9.156.1.3.1.1.2' }, + ccmGatewayStatus => { oid => '.1.3.6.1.4.1.9.9.156.1.3.1.1.5', map => \%mapping_status }, +}; + +my $oid_ccmGatewayEntry = '.1.3.6.1.4.1.9.9.156.1.3.1.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table(oid => $oid_ccmGatewayEntry, start => $mapping->{ccmGatewayName}->{oid}, end => $mapping->{ccmGatewayStatus}->{oid}, nothing_quit => 1); + + $self->{phone} = {}; + $self->{global} = { unknown => 0, registered => 0, unregistered => 0, rejected => 0, partiallyregistered => 0 }; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{ccmGatewayStatus}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{phone}->{$instance} = { %$result }; + $self->{global}->{$result->{ccmGatewayStatus}}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check gateway usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='status' + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /^registered/'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. + +=item B<--critical-*> + +Threshold critical. + +Can be: 'total-registered', 'total-unregistered', 'total-rejected', +'total-unknown', 'total-partiallyregistered'. + +=back + +=cut diff --git a/network/cisco/callmanager/snmp/mode/mediadeviceusage.pm b/network/cisco/callmanager/snmp/mode/mediadeviceusage.pm new file mode 100644 index 000000000..3409e5b9d --- /dev/null +++ b/network/cisco/callmanager/snmp/mode/mediadeviceusage.pm @@ -0,0 +1,223 @@ +# +# 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::cisco::callmanager::snmp::mode::mediadeviceusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +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 = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_ccmMediaDeviceStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_ccmMediaDeviceName'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'md', type => 1, cb_prefix_output => 'prefix_md_output', message_multiple => 'All media devices are ok' }, + ]; + + $self->{maps_counters}->{md} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'ccmMediaDeviceStatus' }, { name => 'ccmMediaDeviceName' } ], + 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'), + } + }, + ]; + + my @map = ( + ['total-registered', 'Registered : %s', 'registered'], + ['total-unregistered', 'Unregistered : %s', 'unregistered'], + ['total-rejected', 'Rejected : %s', 'rejected'], + ['total-unknown', 'Unknown : %s', 'unknown'], + ['total-partiallyregistered', 'Partially Registered : %s', 'partiallyregistered'], + ); + + $self->{maps_counters}->{global} = []; + foreach (@map) { + my $label = $_->[0]; + $label =~ tr/-/_/; + push @{$self->{maps_counters}->{global}}, { label => $_->[0], set => { + key_values => [ { name => $_->[2] } ], + output_template => $_->[1], + perfdatas => [ + { label => $label, value => $_->[2] . '_absolute', template => '%s', min => 0 }, + ], + } + }, + } +} + +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 => + { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /^registered/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_md_output { + my ($self, %options) = @_; + + return "Media device '" . $options{instance_value}->{ccmMediaDeviceName} . "' "; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Total "; +} + +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 %mapping_status = ( + 1 => 'unknown', 2 => 'registered', 3 => 'unregistered', + 4 => 'rejected', 5 => 'partiallyregistered', +); + +my $mapping = { + ccmMediaDeviceName => { oid => '.1.3.6.1.4.1.9.9.156.1.6.1.1.2' }, + ccmMediaDeviceStatus => { oid => '.1.3.6.1.4.1.9.9.156.1.6.1.1.5', map => \%mapping_status }, +}; + +my $oid_ccmMediaDeviceEntry = '.1.3.6.1.4.1.9.9.156.1.6.1.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table(oid => $oid_ccmMediaDeviceEntry, start => $mapping->{ccmMediaDeviceName}->{oid}, end => $mapping->{ccmMediaDeviceStatus}->{oid}, nothing_quit => 1); + + $self->{md} = {}; + $self->{global} = { unknown => 0, registered => 0, unregistered => 0, rejected => 0, partiallyregistered => 0 }; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{ccmMediaDeviceStatus}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{md}->{$instance} = { %$result }; + $self->{global}->{$result->{ccmMediaDeviceStatus}}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check media device usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='status' + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /^registered/'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. + +=item B<--critical-*> + +Threshold critical. + +Can be: 'total-registered', 'total-unregistered', 'total-rejected', +'total-unknown', 'total-partiallyregistered'. + +=back + +=cut diff --git a/network/cisco/callmanager/snmp/mode/phoneusage.pm b/network/cisco/callmanager/snmp/mode/phoneusage.pm new file mode 100644 index 000000000..c72b51bf0 --- /dev/null +++ b/network/cisco/callmanager/snmp/mode/phoneusage.pm @@ -0,0 +1,223 @@ +# +# 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::cisco::callmanager::snmp::mode::phoneusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +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 = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_ccmPhoneStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_ccmPhoneDescription'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'phone', type => 1, cb_prefix_output => 'prefix_phone_output', message_multiple => 'All phones are ok' }, + ]; + + $self->{maps_counters}->{phone} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'ccmPhoneStatus' }, { name => 'ccmPhoneDescription' } ], + 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'), + } + }, + ]; + + my @map = ( + ['total-registered', 'Registered : %s', 'registered'], + ['total-unregistered', 'Unregistered : %s', 'unregistered'], + ['total-rejected', 'Rejected : %s', 'rejected'], + ['total-unknown', 'Unknown : %s', 'unknown'], + ['total-partiallyregistered', 'Partially Registered : %s', 'partiallyregistered'], + ); + + $self->{maps_counters}->{global} = []; + foreach (@map) { + my $label = $_->[0]; + $label =~ tr/-/_/; + push @{$self->{maps_counters}->{global}}, { label => $_->[0], set => { + key_values => [ { name => $_->[2] } ], + output_template => $_->[1], + perfdatas => [ + { label => $label, value => $_->[2] . '_absolute', template => '%s', min => 0 }, + ], + } + }, + } +} + +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 => + { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /^registered/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_phone_output { + my ($self, %options) = @_; + + return "Phone '" . $options{instance_value}->{ccmPhoneDescription} . "' "; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Total "; +} + +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 %mapping_status = ( + 1 => 'unknown', 2 => 'registered', 3 => 'unregistered', + 4 => 'rejected', 5 => 'partiallyregistered', +); + +my $mapping = { + ccmPhoneDescription => { oid => '.1.3.6.1.4.1.9.9.156.1.2.1.1.4' }, + ccmPhoneStatus => { oid => '.1.3.6.1.4.1.9.9.156.1.2.1.1.7', map => \%mapping_status }, +}; + +my $oid_ccmPhoneEntry = '.1.3.6.1.4.1.9.9.156.1.2.1.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table(oid => $oid_ccmPhoneEntry, start => $mapping->{ccmPhoneDescription}->{oid}, end => $mapping->{ccmPhoneStatus}->{oid}, nothing_quit => 1); + + $self->{phone} = {}; + $self->{global} = { unknown => 0, registered => 0, unregistered => 0, rejected => 0, partiallyregistered => 0 }; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{ccmPhoneStatus}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{phone}->{$instance} = { %$result }; + $self->{global}->{$result->{ccmPhoneStatus}}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check phone usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='status' + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /^registered/'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. + +=item B<--critical-*> + +Threshold critical. + +Can be: 'total-registered', 'total-unregistered', 'total-rejected', +'total-unknown', 'total-partiallyregistered'. + +=back + +=cut diff --git a/network/cisco/callmanager/snmp/plugin.pm b/network/cisco/callmanager/snmp/plugin.pm new file mode 100644 index 000000000..2a943ae1d --- /dev/null +++ b/network/cisco/callmanager/snmp/plugin.pm @@ -0,0 +1,51 @@ +# +# 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::cisco::callmanager::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; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'ccm-usage' => 'network::cisco::callmanager::snmp::mode::ccmusage', + 'gateway-usage' => 'network::cisco::callmanager::snmp::mode::gatewayusage', + 'mediadevice-usage' => 'network::cisco::callmanager::snmp::mode::mediadeviceusage', + 'phone-usage' => 'network::cisco::callmanager::snmp::mode::phoneusage', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Cisco Call Manager (CCM) in SNMP. + +=cut